Merge branch 'ysm1' of https://bdgit.educoder.net/Hjqreturn/educoder into yslcompetition

dev_sync_trustie
杨树林 5 years ago
commit 062ed74966

@ -9,6 +9,7 @@
//= require bootstrap-notify
//= require jquery.cookie.min
//= require select2
//= require moment.min
//= require jquery.cxselect
//= require bootstrap-datepicker
//= require bootstrap-datetimepicker

@ -9,9 +9,9 @@ $(document).on('turbolinks:load', function(){
};
var timeOptions = {
autoclose: true,
autoclose: 1,
language: 'zh-CN',
format: 'yyyy-mm-dd hh:ii:ss',
format: 'yyyy-mm-dd hh:ii',
minuteStep: 30
};
@ -23,18 +23,14 @@ $(document).on('turbolinks:load', function(){
$(element).find('.end-date').datepicker('setStartDate', e.date);
});
};
$(".competition-start-end-date .start-date").datetimepicker(timeOptions);
$(".competition-start-end-date .end-date").datetimepicker(timeOptions);
// var defineTimeRangeSelect = function (element) {
// var options = $.extend({inputs: $(element).find('.start-date, .end-date')}, timeOptions);
// $(element).datetimepicker(options);
//
// $(element).find('.start-date').datetimepicker().on('changeDate', function (e) {
// $(element).find('.end-date').datetimepicker('setStartDate', e.date);
// });
// };
$(".nav-setting-form .enroll_end_time").datetimepicker(timeOptions);
defineDateRangeSelect('.teaching-mode-date');
defineDateRangeSelect('.competition-start-end-date');
// defineTimeRangeSelect('.competition-start-end-date');
var $basicForm = $('form.basic-setting-form');
@ -59,13 +55,13 @@ $(document).on('turbolinks:load', function(){
if ($("input[name='mode']:checked").val() == 2) {
var $courseId = $("input[name='course_id'");
if ($courseId.val() === undefined || $course_id.val().length === 0) {
if ($courseId.val() === undefined || $courseId.val().length === 0) {
$courseId.addClass('danger text-danger');
valid = false;
} else {
$courseId.removeClass('danger text-danger');
}
} else if ($("input[name='mode']:checked").val() == 4) {
} else if ($("input[name='mode']:checked").val() == 3) {
var $techStartTime = $("input[name='teach_start_time'");
var $techEndTime = $("input[name='teach_end_time'");
if ($techStartTime.val() === undefined || $techStartTime.val().length === 0) {
@ -81,6 +77,10 @@ $(document).on('turbolinks:load', function(){
} else {
$techEndTime.removeClass('danger text-danger');
}
} else {
$("input[name='course_id'").removeClass('danger text-danger');
$("input[name='teach_start_time'").removeClass('danger text-danger');
$("input[name='teach_end_time'").removeClass('danger text-danger');
}
if (!valid) return;
@ -110,80 +110,80 @@ $(document).on('turbolinks:load', function(){
$(function () {
//MD编辑
$("#MD_typeFrom").on("click",".add_MD_type",function () {
var length=$(".MD_type").find(".add_MD_type").length + 1;
var html='<div class="row MD_type mt-2">\n' +
' <div class="col-1 text-right">\n' +
' <label class="checkbox checkbox-primary mt-1">\n' +
' <input id="checkbox_MD_'+length+'" type="checkbox" name="checkbox_MD_'+length+'">\n' +
' <label for="checkbox_MD_'+length+'">&nbsp;</label>\n' +
' </label>\n' +
' </div>\n' +
' <div class="col-md-4"><input type="text" class="form-control" name="MD_type_value_'+length+'" placeholder="导航名称"></div>\n' +
' <div class="col-md-1"><input type="text" class="form-control" name="MD_type_index_'+length+'" /></div>\n' +
' <button class="btn btn-primary waves-effect waves-light btn-xs setBtn_s add_MD_type">+</button>\n' +
' <button class="btn btn-icon waves-effect btn-default waves-light setBtn_s ml10 del_MD_type">×</button>\n' +
' </div>';
$("#MD_typeFrom").append(html);
})
$("#MD_typeFrom").on("click",".del_MD_type",function () {
$(this).parents(".MD_type").remove();
})
// $("#MD_typeFrom").on("click",".add_MD_type",function () {
//
// var length=$(".MD_type").find(".add_MD_type").length + 1;
// var html='<div class="row MD_type mt-2">\n' +
// ' <div class="col-1 text-right">\n' +
// ' <label class="checkbox checkbox-primary mt-1">\n' +
// ' <input id="checkbox_MD_'+length+'" type="checkbox" name="checkbox_MD_'+length+'">\n' +
// ' <label for="checkbox_MD_'+length+'">&nbsp;</label>\n' +
// ' </label>\n' +
// ' </div>\n' +
// ' <div class="col-md-4"><input type="text" class="form-control" name="MD_type_value_'+length+'" placeholder="导航名称"></div>\n' +
// ' <div class="col-md-1"><input type="text" class="form-control" name="MD_type_index_'+length+'" /></div>\n' +
// ' <button class="btn btn-primary waves-effect waves-light btn-xs setBtn_s add_MD_type">+</button>\n' +
// ' <button class="btn btn-icon waves-effect btn-default waves-light setBtn_s ml10 del_MD_type">×</button>\n' +
// ' </div>';
// $("#MD_typeFrom").append(html);
// })
// $("#MD_typeFrom").on("click",".del_MD_type",function () {
// $(this).parents(".MD_type").remove();
// })
//链接
$("#linkForm").on("click",".add_linkBtn",function () {
var length=$("#linkForm").find(".linkFormItem").length + 1;
var html='<div class="row mt-2 lineFromItem">\n' +
$(".nav-setting-form").on("click",".add_linkBtn",function () {
var length=$(".nav-setting-form").find(".linkFormItem").length + 1;
var html='<div class="row mt-2 align-items-center linkFormItem">\n' +
' <div class="col-1 text-right">\n' +
' <label class="checkbox checkbox-primary mt-1">\n' +
' <input id="link_'+length+'" type="checkbox" name="link_'+length+'" />\n' +
' <label for="link_'+length+'">&nbsp;</label>\n' +
' <input type="checkbox" name="navbar[][hidden]" value="0" class="font-16" checked="checked">\n' +
' </label>\n' +
' </div>\n' +
' <div class="col-md-label mt-1"><input type="text" name="link_name_'+length+'" class="form-control"></div>\n' +
' <div class="col-md-1 mt-1"><input type="text" name="link_index_'+length+'" class="form-control"></div>\n' +
' <div class="col-md-3 mt-1"><input type="text" name="link_info_'+length+'" class="form-control"></div>\n' +
' <button class="mt-1 btn btn-primary waves-effect waves-light btn-xs setBtn_s add_linkBtn">+</button>\n' +
' <button class="mt-1 btn btn-icon waves-effect btn-default waves-light setBtn_s ml10 del_linkBtn">×</button>\n' +
' </div>'
$("#linkForm").append(html)
})
$("#linkForm").on("click",".del_linkBtn",function () {
$(this).parents(".lineFromItem").remove();
})
' <div class="col-md-label mt-1"><input type="hidden" value="md" name="navbar[][module_type]">\n' +
' <input type="text" name="navbar[][name]" value="" class="form-control" placeholder="模块名称"></div>\n' +
' <div class="col-md-1 mt-1"><input type="text" name="navbar[][position]" value="" class="form-control" placeholder="位置"></div>\n' +
' <div class="col-md-3 mt-1"><input type="text" name="navbar[][url]" value="" class="form-control" placeholder="请输入资料下载地址"></div>\n' +
' <a class="mt-1 btn btn-primary waves-effect waves-light btn-xs setBtn_s add_linkBtn" href="javascript:void(0)">+</a>\n' +
' <a class="mt-1 btn btn-icon waves-effect btn-default waves-light setBtn_s ml10 del_linkBtn" href="javascript:void(0)">×</a>\n' +
' </div>';
$(this).parents(".linkFormItem").after(html);
});
$(".nav-setting-form").on("click", ".del_linkBtn", function () {
$(this).parents(".linkFormItem").remove();
});
//有关报名要求
$("#addRequireBtn").on("click",function () {
$(".addRequireBtn").on("click",function () {
var length=$("#requireForm").find(".requireForm_item").length + 1;
var html='<div class="row mt-2 mb-4 requireForm_item">\n' +
' <div class="col-1 text-right">&nbsp;&nbsp;</div>\n' +
' <div class="col-1 text-left mt-1">\n' +
' <input type="text" class="form-control" name="min_'+length+'" />\n' +
' <input type="text" class="form-control" name="competition_staffs[][minimum]" value="0">\n' +
' </div>\n' +
' <span class="mt-2">~</span>\n' +
' <div class="col-1 mt-1">\n' +
' <input type="text" class="form-control" name="max_'+length+'" />\n' +
' <input type="text" class="form-control" name="competition_staffs[][maximum]" value="1">\n' +
' </div>\n' +
' <span class="mt-2">人</span>\n' +
' <div class="col-2 mt-1">\n' +
' <select class="form-control" name="choice_'+length+'" >\n' +
' <option>不限</option>\n' +
' <option>教师</option>\n' +
' <option>学生</option>\n' +
' <option>专业人士</option>\n' +
' <select class="form-control" name="competition_staffs[][category]">\n' +
' <option value="all">不限</option>\n' +
' <option value="teacher">教师</option>\n' +
' <option value="student">学生</option>\n' +
' <option value="profession">专业人士</option>\n' +
' </select>\n' +
' </div>\n' +
' <div class="col-2 mt-1">\n' +
' <label class="radio checkbox-primary mt-1" value="require_'+length+'_1">\n' +
' <input id="require_'+length+'_1" name="require_1" type="radio">\n' +
' <input id="require_'+length+'_1" class="mutiple-limited-radio" value="false" checked name="competition_staffs[][mutiple_limited]" type="checkbox">\n' +
' <label for="require_'+length+'_1">可多次报名</label>\n' +
' </label>\n' +
' </div>\n' +
' <div class="col-2 mt-1">\n' +
' <label class="radio checkbox-primary mt-1" value="require_'+length+'_2">\n' +
' <input id="require_'+length+'_2" name="require_1" type="radio">\n' +
' <input id="require_'+length+'_2" class="mutiple-limited-radio" value="true" name="competition_staffs[][mutiple_limited]" type="checkbox">\n' +
' <label for="require_'+length+'_2">不可多次报名</label>\n' +
' </label>\n' +
' <a href="javascript:void(0)" class="ml20 delRequrieBtn">\n' +
@ -192,9 +192,189 @@ $(function () {
' </div>\n' +
' </div>';
$("#requireForm").append(html);
})
});
$("#requireForm").on("click",".delRequrieBtn",function () {
$(this).parents(".requireForm_item").remove();
})
})
$('.competition-staff-settings').on('click', '.mutiple-limited-radio', function(){
var radio = $(this);
if (radio.is(':checked')) {
radio.parent().parent().siblings().find('.mutiple-limited-radio').attr('checked', false)
} else {
radio.parent().parent().siblings().find('.mutiple-limited-radio').attr('checked', true)
}
});
var $navForm = $('form.nav-setting-form');
$navForm.on('click', ".submit-btn", function () {
$navForm.find('.submit-btn').attr('disabled', 'disabled');
$navForm.find('.error').html('');
var valid = $navForm.valid();
if (!valid) return;
$.ajax({
method: 'POST',
dataType: 'json',
url: $navForm.attr('action'),
data: new FormData($navForm[0]),
processData: false,
contentType: false,
success: function (data) {
$.notify({message: '保存成功'});
// window.location.reload();
},
error: function (res) {
var data = res.responseJSON;
$navForm.find('.error').html(data.message);
},
complete: function () {
$navForm.find('.submit-btn').attr('disabled', false);
}
});
});
// 排行榜设置
//删除小阶段
$("#large_panel").on("click",".small_panel_item_del",function () {
var list = $(this).parents(".small_panel");
$(this).parents(".small_panel_item").remove();
for(var i=0;i < $(list).find(".subName").length;i++){
console.log(i);
$(list).find(".subName").eq(i).html("第"+parseInt(i+1)+"阶段");
}
})
})
//新增子阶段
function add_task_sub(item){
var index = $(item).parents(".large_panel_part").attr("attr_line");
var count= 0;
console.log("sdfsf");
console.log($("#small_panel_"+index).find(".small_panel_item").length > 0);
if($("#small_panel_"+index).find(".small_panel_item").length > 0){
count = parseInt($("#small_panel_"+index).find(".small_panel_item").last().attr("count")) + 1;
console.log($("#small_panel_"+index).find(".small_panel_item").last().attr("count"));
}else{
count = 1;
}
var showCount=parseInt($("#small_panel_"+index).find(".small_panel_item").length) + 1;
var html='<div class="row d-flex small_panel_item" attr_line="sub_'+index+'_'+count+'" count="'+count+'">\n' +
' <span class="col-1 mt-2 subName">第'+showCount+'阶段</span>\n' +
' <div class="flex-1">\n' +
' <div class="row">\n' +
' <span class="mt-2 ml20">有效时间:</span>\n' +
' <div class="col-2 no_padding input_middle">\n' +
' <input class="use_time_begin_'+index+'_'+count+' form-control" placeholder="有效开始时间"/>\n' +
' </div>\n' +
' <span class="mt-2">~</span>\n' +
' <div class="col-2 no_padding input_middle">\n' +
' <input class="use_time_end_'+index+'_'+count+' form-control" placeholder="有效结束时间"/>\n' +
' </div>\n' +
' <span class="col-2 text-right mt-2 no_padding">任务完成要求:</span>\n' +
' <div class="col-1 no_padding input_small">\n' +
' <input type="number" class="form-control" name="task_require_small_'+index+'_'+count+'"/>\n' +
' </div>\n' +
' <span class="mt-2 ml10 mr10">/</span>\n' +
' <div class="col-1 no_padding input_small">\n' +
' <input type="number" class="form-control task_all" onchange="change_total(this)" name="task_require_all_'+index+'_'+count+'"/>\n' +
' </div>\n' +
' <span class=" mt-2">(总任务)</span>\n' +
' <span class="col-1 text-right mt-2 no_padding">成绩来源:</span>\n' +
' <div class="col-2 no_padding input_middle">\n' +
' <select class="form-control" name="source_'+index+'_'+count+'">\n' +
' <option>经验值</option>\n' +
' <option>预测准确率</option>\n' +
' </select>\n' +
' </div>\n' +
' </div>\n' +
' <div class="row mt-2" id="task_Input_sub_'+index+'_'+count+'"></div>\n' +
' </div>\n' +
' <span>\n' +
' <a href="javascript:void(0)" class="btn btn-default ml20 small_panel_item_del">删除</a>\n' +
' </span>\n' +
' </div>';
$("#small_panel_"+index).append(html);
}
// 小阶段修改总任务数
function change_total(item) {
var count=parseInt($(item).val());
var index = $(item).parents(".small_panel_item").attr("attr_line");
var indexLarge = $(item).parents(".large_panel_part").attr("attr_line");
console.log(indexLarge);
console.log(index);
var divCount=parseInt($("#task_Input_"+index).find(".task_Input_div").length);
var html = "";
if(count > divCount){
for(var i=0;i < count-divCount ;i++){
html+='<div class="col-4 row task_Input_div"><span class="col-3 text-center mt-3">任务'+(divCount+i+1)+'</span>\n' +
'<div class="col-8">\n' +
'<input type="text" class="form-control mt-2" name="input_'+index+'_'+(divCount+i+1) +'" placeholder="请填写实训ID">\n' +
'</div>\n' +
'</div>';
}
$("#task_Input_"+index).append(html);
}else{
var delCount = divCount - count ;
console.log(divCount);
console.log(count);
var _max=parseInt($("#task_Input_"+index).find(".task_Input_div:last").index());
console.log(_max);
var _get= _max - delCount;
console.log(_get);
if(count == 0){
$("#task_Input_"+index).empty();
}else{
$("#task_Input_"+index).find(".task_Input_div:gt("+_get+")").remove();
}
}
}
//删除tab
function Del_tab(item) {
$(item).parents(".large_panel_part").remove();
}
//新增tab
function addNewTab() {
var count = parseInt($("#large_panel").find(".large_panel_part").length)+1;
var html = '<div class="large_panel_part" attr_line="'+count+'"><div class="row d-flex mt-3">\n' +
' <span class="col-1 mt-2">tab标题</span>\n' +
' <div class="col-2 no_padding">\n' +
' <input type="text" class="form-control" name="tab_title_1"/>\n' +
' </div>\n' +
' <span class="col-1 text-right mt-2 no_padding">总排行榜占比:</span>\n' +
' <div class="col-1 no_padding">\n' +
' <input type="number" class="form-control" name="tab_percent_'+count+'"/>\n' +
' </div><span class=" mt-2">%</span>\n' +
' <div class="flex-1">\n' +
' <a href="javascript:void(0)"class="btn btn-outline-primary export-action ml20 add_task_sub" onclick="add_task_sub(this)">新增子阶段</a>\n' +
' <a href="javascript:void(0)" class="btn btn-outline-primary export-action ml20">发送短信提醒</a>\n' +
' <a href="javascript:void(0)" class="btn btn-outline-primary export-action ml20">计算成绩</a>\n' +
' </div>\n' +
' <a href="javascript:void(0)" class="btn btn-default ml20" onclick="Del_tab(this)">删除</a>\n' +
' <a href="javascript:void(0)" class="btn btn-outline-primary export-action ml20">保存</a>\n' +
' </div>\n' +
' <div id="small_panel_'+count+'" class="small_panel"></div></div>';
$("#large_panel").append(html);
}

@ -1,6 +1,6 @@
$(document).on('turbolinks:load', function() {
if($('body.admins-enroll-lists-index-page').length > 0){
let search_form = $(".search-form");
var search_form = $(".search-form");
//导出
$(".competition-enroll-list-form").on("click","#enroll-lists-export",function () {
window.location.href = "/admins/competitions/"+$(this).attr("data-competition-id")+"/enroll_lists/export.xlsx?" + search_form.serialize();

@ -135,7 +135,7 @@ $(document).on('turbolinks:load', function() {
},
templateResult: function (item) {
if(!item.id || item.id === '') return item.text;
return item.real_name;
return $("<span>" + item.real_name + " <span class='font-12'>" + item.school_name + ' ' + item.hidden_phone + "</span></span>");
},
templateSelection: function(item){
if (item.id) {

@ -5,7 +5,7 @@ $(document).on('turbolinks:load', function() {
allowClear: true
});
let search_form = $(".search-form");
var search_form = $(".search-form");
//导出
$(".shixuns-list-form").on("click","#shixuns-export",function () {
window.location.href = "/admins/shixuns.xls?" + search_form.serialize();

@ -15,15 +15,19 @@ $(document).on('turbolinks:load', function(){
var $unlockAction = $lockAction.siblings('.unlock-action');
var userId = $lockAction.data('id');
$.ajax({
url: '/admins/users/' + userId + '/lock',
method: 'POST',
dataType: 'json',
success: function() {
showSuccessNotify();
$lockAction.hide();
$unlockAction.show();
customConfirm({
content: '确认加锁吗?',
ok: function(){
$.ajax({
url: '/admins/users/' + userId + '/lock',
method: 'POST',
dataType: 'json',
success: function() {
showSuccessNotify();
$lockAction.hide();
$unlockAction.show();
}
});
}
});
});
@ -34,17 +38,21 @@ $(document).on('turbolinks:load', function(){
var $lockAction = $unlockAction.siblings('.lock-action');
var userId = $unlockAction.data('id');
$.ajax({
url: '/admins/users/' + userId + '/unlock',
method: 'POST',
dataType: 'json',
success: function() {
showSuccessNotify();
$lockAction.show();
$unlockAction.hide();
customConfirm({
content: '确认解锁吗?',
ok: function () {
$.ajax({
url: '/admins/users/' + userId + '/unlock',
method: 'POST',
dataType: 'json',
success: function() {
showSuccessNotify();
$lockAction.show();
$unlockAction.hide();
}
});
}
});
})
});
// active user
@ -54,18 +62,22 @@ $(document).on('turbolinks:load', function(){
var $lockAction = $activeAction.siblings('.lock-action');
var userId = $activeAction.data('id');
$.ajax({
url: '/admins/users/' + userId + '/unlock',
method: 'POST',
dataType: 'json',
success: function() {
showSuccessNotify();
$activeAction.hide();
$lockAction.show();
$unlockAction.hide();
customConfirm({
content: '确认激活吗?',
ok: function () {
$.ajax({
url: '/admins/users/' + userId + '/unlock',
method: 'POST',
dataType: 'json',
success: function() {
showSuccessNotify();
$activeAction.hide();
$lockAction.show();
$unlockAction.hide();
}
});
}
});
})
});
// ***************** reward grade modal *****************

File diff suppressed because it is too large Load Diff

@ -27,7 +27,7 @@ $(document).on('turbolinks:load', function() {
},
templateResult: function (item) {
if(!item.id || item.id === '') return item.text;
return item.real_name + "--" + item.identity;
return $("<span>" + item.real_name + " <span class='font-12'>" + item.school_name + ' ' + item.hidden_phone + "</span></span>");
},
templateSelection: function(item){
if (item.id) {

@ -0,0 +1,16 @@
/**
* Simplified Chinese translation for bootstrap-datetimepicker
* Yuan Cheung <advanimal@gmail.com>
*/
;(function($){
$.fn.datetimepicker.dates['zh-CN'] = {
days: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"],
daysShort: ["周日", "周一", "周二", "周三", "周四", "周五", "周六", "周日"],
daysMin: ["日", "一", "二", "三", "四", "五", "六", "日"],
months: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"],
monthsShort: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"],
today: "今天",
suffix: [],
meridiem: ["上午", "下午"]
};
}(jQuery));

File diff suppressed because one or more lines are too long

@ -7,6 +7,7 @@
@import "bootstrap-datepicker.standalone";
@import "jquery.mloading";
@import "jquery-confirm.min";
@import "bootstrap-datetimepicker.min";
@import "codemirror/lib/codemirror";
@import "editormd/css/editormd.min";

@ -37,6 +37,28 @@
}
.setBtn_s{
height: 35px;
line-height: 5px;
line-height: 20px;
}
.large_panel{
padding:0px 15px;
.large_panel_part{
border-top: 1px solid #eaeaea;
}
.large_panel_part:first-child{
border:none;
}
.large_panel_part >.row ,.small_panel >.row{
border-bottom: 1px solid #eaeaea;
padding:20px 0px;
}
.small_panel{
margin-left: 20px;
}
.row:last-child{
border:none;
}
}
}

File diff suppressed because one or more lines are too long

@ -29,7 +29,7 @@ input.form-control {
.flex-1 {
flex: 1;
}
.no_padding{padding: 0px!important;}
.font-12 { font-size: 12px !important; }
.font-14 { font-size: 14px !important; }
.font-16 { font-size: 16px !important; }
@ -48,6 +48,10 @@ input.form-control {
.position-r{position:relative;}
.color-grey-c{color:#ccc}
.color-blue{color:#4CACFF}
.color-orange{color: #ff6800}
.inline-block{display:inline-block;}
.hide{display: none;}
.show{display: block;}
.input_small{flex: 0 0 6%!important;}
.input_middle{flex:0 0 13%!important;}

@ -20,10 +20,10 @@ class Admins::CompetitionSettingsController < Admins::BaseController
end
def basic_form_params
params.permit(:identifier, :name, :sub_title, :start_time, :end_time, :mode, :identifier, :bonus, :awards_count, :description, :course_id, :teach_start_time, :teach_end_time)
params.permit(:identifier, :name, :sub_title, :sponsor_schools, :region_schools, :start_time, :end_time, :mode, :identifier, :bonus, :awards_count, :description, :course_id, :teach_start_time, :teach_end_time)
end
def nav_form_params
params.permit(:enroll_end_time, competition_staffs: %i[category minimum maximum mutiple_limited], nav_module: %i[module_type name hidden position url])
params.permit(:enroll_end_time, competition_staffs: %i[category minimum maximum mutiple_limited], navbar: %i[module_type name hidden position url])
end
end

@ -32,13 +32,13 @@ class Admins::UsersController < Admins::BaseController
end
def lock
User.find(params[:user_id]).lock!
User.find(params[:id]).lock!
render_ok
end
def unlock
User.find(params[:user_id]).activate!
User.find(params[:id]).activate!
render_ok
end

@ -59,6 +59,7 @@ class Competitions::CompetitionTeamsController < Competitions::BaseController
end
def index
@competition = current_competition
@personal = current_competition.personal?
if admin_or_business?
all_competition_teams
@ -135,7 +136,7 @@ class Competitions::CompetitionTeamsController < Competitions::BaseController
def tech_mode
# render_not_found if current_competition.mode != 3
@team = current_competition.competition_teams.find_by(id: params[:id])
@team = current_competition.competition_teams.find_by!(id: params[:id])
end
def get_valid_myshixun_count(ids)

@ -70,12 +70,15 @@ class Competitions::CompetitionsController < Competitions::BaseController
def update_md_content
tip_exception("标题和内容不能为空") if params[:name].blank? || params[:content].blank?
tip_exception("缺少competition_module_id") if params[:competition_module_id].blank?
ActiveRecord::Base.transaction do
com_module = current_competition.competition_modules.find_by!(id: params[:competition_module_id])
if params[:md_content_id]
md_content = CompetitionModuleMdContent.find_by!(id: params[:md_content_id])
md_content = CompetitionModuleMdContent.find_by!(id: params[:md_content_id], competition_module_id: com_module.id)
md_content.update_attributes!(name: params[:name], content: params[:content])
else
md_content = CompetitionModuleMdContent.create!(name: params[:name], content: params[:content])
stage = current_competition.competition_stages.find_by(id: params[:stage_id]) if params[:stage_id]
md_content = CompetitionModuleMdContent.create!(name: params[:name], content: params[:content], competition_module_id: com_module.id, competition_stage_id: stage&.id.to_i)
end
Attachment.associate_container(params[:attachment_ids], md_content.id, md_content.class) if params[:attachment_ids]
normal_status("更新成功")
@ -84,8 +87,8 @@ class Competitions::CompetitionsController < Competitions::BaseController
def chart_rules
@competition = current_competition
@stages = @competition.competition_stages
@rule_contents = @competition.chart_rules
com_module = @competition.competition_modules.find_by(module_type: "chart")
@rule_contents = com_module&.competition_module_md_contents
end
def update_chart_rules

@ -7,6 +7,7 @@ class Competitions::StudentsController < Competitions::BaseController
end
students = User.joins(:user_extension).where(status: 1, user_extensions: { identity: 1 })
students = students.where(user_extensions: { school_id: current_competition.region_schools.pluck(:school_id) }) if current_competition.region_schools.size > 0
students = students.where.not(id: params[:student_ids]) if params[:student_ids].present?
students = students.where('LOWER(CONCAT(lastname, firstname, login, nickname)) LIKE ?', "%#{keyword}%")
@students = students.includes(user_extension: :school).limit(20)

@ -2,9 +2,14 @@ class Cooperative::UsersController < Cooperative::BaseController
def index
params[:sort_by] = params[:sort_by].presence || 'created_on'
params[:sort_direction] = params[:sort_direction].presence || 'desc'
params[:school_id] = current_laboratory.school_id
users = Admins::UserQuery.call(params)
users = Admins::UserQuery.call(search_params)
@users = paginate users.includes(user_extension: :school)
end
private
def search_params
params.permit(:name, :sort_by, :sort_direction)
end
end

@ -86,6 +86,7 @@ class Competitions::SaveTeamForm
# 创建者是否能多次报名
def check_creator_multiple_enrollable
return unless team.new_record? # 编辑战队时不需要校验
return unless competition.enrolled?(creator)
if (creator.is_teacher? && competition.teacher_multiple_limited?) || (!creator.is_teacher? && competition.member_multiple_limited?)

@ -37,7 +37,7 @@ module CompetitionsHelper
def chart_stages competition
stages = []
statistic_stages = competition.competition_stages.where("rate > 0")
statistic_stages = competition.competition_stages.where("score_rate > 0")
if competition.end_time && competition.end_time < Time.now && statistic_stages.size > 1
stages << {id: nil, name: "总排行榜", rate: 1.0, start_time: competition.start_time, end_time: competition.end_time}
end

@ -0,0 +1,25 @@
require 'uri'
require 'net/http'
class SyncTrustieJob < ApplicationJob
queue_as :default
def perform(type, count)
Rails.logger.info("#######_________response__sync__start__#########")
configs_content = Rails.application.config_for(:configuration)
token = configs_content["sync_token"]
token_url = configs_content["sync_url"]
url = "#{token_url}/api/v1/homes/sync_count"
sync_json = {
"token": token,
"type": type,
"number": count
}
uri = URI.parse(url)
http = Net::HTTP.new(uri.hostname, uri.port)
http.send_request('PUT', uri.path, sync_json.to_json, {'Content-Type' => 'application/json'})
Rails.logger.info("#######_________response__sync__end_____#########")
end
end

@ -60,7 +60,7 @@ module Util
return if str.blank?
case type
when :phone then "#{str[0..2]}***#{str[-3..-1]}"
when :phone then "#{str[0..2]}****#{str[-4..-1]}"
when :email then "#{str[0]}***#{str[(str.rindex('@')-1)..-1]}"
else "#{str[0..2]}***#{str[-3..-1]}"
end

@ -22,6 +22,9 @@ class Competition < ApplicationRecord
has_many :attachments, as: :container, dependent: :destroy
has_many :competition_awards, dependent: :destroy
has_many :competition_schools, dependent: :destroy
has_one :sponsor_schools, -> { where(source: :sponsor) }, class_name: 'CompetitionSchool' # 主办方
has_one :region_schools, -> { where(source: :region) }, class_name: 'CompetitionSchool' # 开放范围
after_create :create_competition_modules
@ -66,7 +69,7 @@ class Competition < ApplicationRecord
# 是否为个人赛
def personal?
competition_staffs.maximum(:maximum) == 1 || max_num == 1
competition_staffs.sum(:maximum).to_i == 1 || (competition_staffs.nil? && max_num == 1)
end
# 报名是否结束
@ -79,6 +82,12 @@ class Competition < ApplicationRecord
team_members.exists?(user_id: user.id)
end
# 是否开放
def open?(user)
user_school_id = user.user_extension&.school_id.to_i
competition.region_schools.size == 0 || competition.region_schools.exists?(school_id: user_school_id)
end
# 是否禁止教师报名
def teacher_enroll_forbidden?
teacher_staff.blank? || teacher_staff.maximum.zero?

@ -6,19 +6,13 @@ class CompetitionModule < ApplicationRecord
has_one :competition_module_md_content, dependent: :destroy
def module_url
case module_type
when "home"
"/competitions/#{competition.identifier}"
when "inform"
"/competitions/#{competition.identifier}/informs?status=1"
when "manual"
"/competitions/#{competition.identifier}/informs?status=2"
when "chart"
"/competitions/#{competition.identifier}/charts"
when "enroll"
"/competitions/#{competition.identifier}/competition_teams"
else
url || "/competitions/#{competition.identifier}/md_content?md_content_id=#{competition_module_md_content&.id}"
end
result_url = url.present? ? url : case module_type
when "chart"
"/competitions/#{competition.identifier}/charts.json"
when "enroll"
"/competitions/#{competition.identifier}/competition_teams.json"
else
"/competitions/#{competition.identifier}/competition_modules/#{id}.json"
end
end
end

@ -3,6 +3,6 @@ class CompetitionModuleMdContent < ApplicationRecord
has_many :attachments, as: :container, dependent: :destroy
validates :name, presence: true
# validates :name, presence: true
validates :content, presence: true
end

@ -0,0 +1,5 @@
class CompetitionSchool < ApplicationRecord
# source sponsor: 主办方, region开放范围
belongs_to :competition
belongs_to :school
end

@ -5,6 +5,7 @@ class CompetitionStage < ApplicationRecord
has_many :competition_entries, dependent: :destroy
has_many :competition_scores, dependent: :destroy
has_one :competition_module_md_content, dependent: :destroy
has_one :chart_rule, dependent: :destroy
def min_start_time

@ -8,6 +8,8 @@ class Project < ApplicationRecord
has_many :issues
has_many :user_grades, dependent: :destroy
after_create :sync_project_trustie #同步到trustie
# 创建者
def creator
User.find(user_id).full_name
@ -20,4 +22,8 @@ class Project < ApplicationRecord
def member?(user)
members.exists?(user_id: user.id)
end
def sync_project_trustie
SyncTrustieJob.perform_later("project", 1)
end
end

@ -19,6 +19,8 @@ class School < ApplicationRecord
has_many :apply_add_departments, dependent: :destroy
has_many :user_extensions, dependent: :nullify
after_create :sync_school_trustie #同步到trustie
# 学校管理员
def manager?(user)
ec_school_users.exists?(user_id: user.id)
@ -39,4 +41,8 @@ class School < ApplicationRecord
def manage_permission?(user)
manager?(user) || major_manager?(user) || course_manager?(user)
end
def sync_school_trustie
SyncTrustieJob.perform_later("school", 1)
end
end

@ -75,7 +75,7 @@ class Shixun < ApplicationRecord
scope :field_for_recommend, lambda{ select([:id, :name, :identifier, :myshixuns_count]) }
scope :find_by_ids,lambda{|k| where(id:k)}
after_create :send_tiding
after_create :send_tiding, :sync_shixun_trustie #同步到trustie
# REDO: 
def propaedeutics
@ -290,6 +290,10 @@ class Shixun < ApplicationRecord
subjects.where(hidden: 0).uniq
end
def sync_shixun_trustie
SyncTrustieJob.perform_later("practical_training_project", 1)
end
private
def send_tiding

@ -156,6 +156,7 @@ class User < ApplicationRecord
delegate :gender, :department_id, :school_id, :location, :location_city, :technical_title, to: :user_extension, allow_nil: true
before_save :update_hashed_password
after_create :sync_user_trustie #同步到trustie
#
# validations
@ -313,6 +314,10 @@ class User < ApplicationRecord
shixun.shixun_members.exists?(role: 2, user_id: id)
end
def sync_user_trustie
SyncTrustieJob.perform_later("user", 1)
end
# TPI的创建者
def creator_of_game?(game)
id == game.user_id
@ -661,6 +666,10 @@ class User < ApplicationRecord
if password.present? && password.size < MIX_PASSWORD_LIMIT && !User.current.admin?
raise("密码长度不能低于#{MIX_PASSWORD_LIMIT}")
end
if password.present? && password.size > 16
raise('密码长度不能超过16位')
end
end
end

@ -20,8 +20,9 @@ class Admins::CompetitionBasicSettingService < ApplicationService
competition.save!
# 竞赛模式相关设置
if competition.mode == 1 || competition.mode == 4
competition.competition_mode_setting.destroy
competition.competition_mode_setting&.destroy
else
setting = competition.competition_mode_setting || CompetitionModeSetting.create!(competition_id: competition.id)
if competition.mode == 2
@ -33,6 +34,23 @@ class Admins::CompetitionBasicSettingService < ApplicationService
setting.save!
end
# 主办方设置
new_school_ids = (params[:sponsor_schools] || []) - competition.sponsor_schools.pluck(:school_id)
delete_school_ids = competition.sponsor_schools.pluck(:school_id) - (params[:sponsor_schools] || [])
new_school_ids.each do |school_id|
CompetitionSchool.create!(competition_id: competition.id, school_id: school_id, source: 'sponsor')
end
competition.sponsor_schools.where(school_id: delete_school_ids).destroy_all
# 开放范围设置
new_region_school_ids = (params[:region_schools] || []) - competition.region_schools.pluck(:school_id)
delete_region_school_ids = competition.region_schools.pluck(:school_id) - (params[:region_schools] || [])
new_region_school_ids.each do |school_id|
CompetitionSchool.create!(competition_id: competition.id, school_id: school_id, source: 'region')
end
competition.region_schools.where(school_id: delete_region_school_ids).destroy_all
competition
end
end

@ -13,16 +13,17 @@ class Admins::CompetitionNavSettingService < ApplicationService
# 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|
params[:navbar].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"])
com_module.update_attributes!(hidden: nav["hidden"] ? 0 : 1, position: nav["position"] ? nav["position"] : com_module.position, name: nav["name"], url: nav["url"])
end
competition.update_attributes!(enroll_end_time: params[:enroll_end_time])
if params[:competition_staffs].present?
competition.competition_staffs.delete_all
params[:competition_staffs].each_with_index do |staff_params, index|

@ -11,6 +11,8 @@ class Competitions::CreatePersonalTeamService < ApplicationService
def call
raise Error, '个人赛才能报名' unless competition.personal?
raise Error, '本竞赛只对指定单位/学校开放' unless competition.open?(user)
is_teacher = user.is_teacher?
raise Error, '本竞赛的参赛者限定为:学生' if is_teacher && competition.teacher_enroll_forbidden?
raise Error, '本竞赛的参赛者限定为:教师' if !is_teacher && competition.member_enroll_forbidden?

@ -13,6 +13,8 @@ class Competitions::JoinTeamService < ApplicationService
invite_code = params[:invite_code].to_s.strip
raise Error, '战队邀请码不能为空' if invite_code.blank?
raise Error, '本竞赛只对指定单位/学校开放' unless competition.open?(user)
is_teacher = user.is_teacher?
raise Error, '本竞赛的参赛者限定为:学生' if is_teacher && competition.teacher_enroll_forbidden?
raise Error, '本竞赛的参赛者限定为:教师' if !is_teacher && competition.member_enroll_forbidden?

@ -32,7 +32,7 @@ class Competitions::SaveTeamService < ApplicationService
private
def update_teacher_team_members!
teacher_ids = Array.wrap(params[:teacher_ids]).map(:to_i)
teacher_ids = Array.wrap(params[:teacher_ids]).map(&:to_i)
old_teacher_ids = team.team_members.where(role: 3).pluck(:user_id)
destroy_teacher_ids = old_teacher_ids - teacher_ids
@ -49,7 +49,7 @@ class Competitions::SaveTeamService < ApplicationService
end
def update_member_team_members!
member_ids = Array.wrap(params[:member_ids]).map(:to_i)
member_ids = Array.wrap(params[:member_ids]).map(&:to_i)
old_member_ids = team.team_members.where(role: 2).pluck(:user_id)
destroy_member_ids = old_member_ids - member_ids

@ -0,0 +1,22 @@
#初始化同步educoder的人数项目数高校数实训数到Trustie平台只需运行一次
class SyncTrustieTask
def sync_format
Rails.logger.info("########________sync_to_trustie_start_________###########")
users_count = User.all.size
projects_count = Project.all.size
shixuns_count = Shixun.all.size
schools_count = School.all.size
SyncTrustieJob.perform_later("user", users_count)
SyncTrustieJob.perform_later("project", projects_count)
SyncTrustieJob.perform_later("practical_training_project", shixuns_count)
SyncTrustieJob.perform_later("school", schools_count)
Rails.logger.info("########________sync_to_trustie_end_________###########")
end
end

@ -35,8 +35,8 @@
起止时间
</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: '竞赛截止时间' %>
<%= text_field_tag :start_time, @competition.start_time&.strftime('%Y-%m-%d %H:%M'), autocomplete: 'off', class: 'form-control start-date mx-0 mr-2', placeholder: '竞赛开始时间' %>
<%= text_field_tag :end_time, @competition.end_time&.strftime('%Y-%m-%d %H:%M'), autocomplete: 'off', class: 'form-control end-date mx-0', placeholder: '竞赛截止时间' %>
</div>
</div>
@ -151,134 +151,235 @@
<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 %>
<%= form_tag(nav_setting_admins_competition_competition_settings_path(@competition), method: :post, class: 'nav-setting-form flex-1', remote: true) do %>
<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="mt-3" id="MD_typeFrom">
<div class="row MD_type">
<div class="col-1 text-right">
<label class="checkbox checkbox-primary mt-1">
<input type="checkbox" name="navbar[][hidden]" value="0" hidden class="font-16" checked="checked">
<input type="checkbox" disabled="disabled" class="font-16" checked="checked">
</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>
<% when 'enroll' %>
<div class="row mt-2">
<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: '首页') %>
<div class="col-md-8 color-blue mt-1">
<input type="hidden" value="<%= com_module.module_type %>" name="navbar[][module_type]">
<input type="hidden" value="报名" name="navbar[][name]">
报名
</div>
</div>
<div class="row mt-2 align-items-center">
<div class="col-1 text-right">&nbsp;&nbsp;</div>
<div class="col-1 text-left" style="max-width: 120px;flex: 0 0 120px;">
报名截止时间
</div>
<div class="col-md-3">
<%= text_field_tag :enroll_end_time, @competition.enroll_end_time&.strftime('%Y-%m-%d %H:%M'), autocomplete: 'off', class: 'form-control enroll_end_time', placeholder: '报名截止时间' %>
</div>
</div>
<div class="row mt-2">
<div class="col-1 text-right">&nbsp;&nbsp;</div>
<div class="col-1 text-left mt-1">
报名要求
</div>
<div class="col-md-3">
<%= javascript_void_link '+', class: 'btn btn-primary waves-effect waves-light btn-xs setBtn_s addRequireBtn' %>
</div>
<div class="col-md-1">
</div>
<div id="requireForm" class="competition-staff-settings">
<% @competition.competition_staffs.each do |staff| %>
<div class="row mt-2 mb-4 requireForm_item">
<div class="col-1 text-right">&nbsp;&nbsp;</div>
<div class="col-1 text-left mt-1">
<input type="text" class="form-control" name="competition_staffs[][minimum]" value="<%= staff.minimum %>" />
</div>
<span class="mt-2">~</span>
<div class="col-1 mt-1">
<input type="text" class="form-control" name="competition_staffs[][maximum]" value="<%= staff.maximum %>" />
</div>
<span class="mt-2">人</span>
<div class="col-2 mt-1">
<select class="form-control" name="competition_staffs[][category]">
<option value="all" <%= staff.category == "all" ? "selected='selected'" : "" %>>不限</option>
<option value="teacher" <%= staff.category == "teacher" ? "selected='selected'" : "" %>>教师</option>
<option value="student" <%= staff.category == "student" ? "selected='selected'" : "" %>>学生</option>
<option value="profession" <%= staff.category == "profession" ? "selected='selected'" : "" %>>专业人士</option>
</select>
</div>
<div class="col-2 mt-1">
<label class="radio checkbox-primary mt-1" value="require_1_1">
<input id="require_1_<%= staff.id %>" <%= staff.mutiple_limited? ? '' : 'checked="checked"' %> class="mutiple-limited-radio" value="false" name="competition_staffs[][mutiple_limited]" type="checkbox">
<label for="require_1_<%= staff.id %>">可多次报名</label>
</label>
</div>
<div class="col-2 mt-1">
<label class="radio checkbox-primary mt-1" value="require_1_2">
<input id="require_2_<%= staff.id %>" <%= staff.mutiple_limited? ? 'checked="checked"' : '' %> class="mutiple-limited-radio" value="true" name="competition_staffs[][mutiple_limited]" type="checkbox">
<label for="require_2_<%= staff.id %>">不可多次报名</label>
</label>
<a href="javascript:void(0)" class="ml20 delRequrieBtn">
<i class="fa fa-times-circle font-20 color-grey-c"></i>
</a>
</div>
</div>
<% end %>
</div>
<% when 'inform', 'chart', 'resource' %>
<div class="row mt-2 new_module_div linkFormItem">
<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-label mt-2">
<input type="hidden" value="<%= com_module.module_type %>" name="navbar[][module_type]">
<input type="hidden" value="<%= com_module.name %>" name="navbar[][name]">
<%= com_module.name %>
</div>
<div class="col-md-1 mt-1">
<%= text_field_tag('navbar[][position]', com_module.position, id: nil, class: 'form-control', placeholder: '位置') %>
</div>
<% if com_module.module_type == "resource" %>
<div class="col-md-3 mt-1">
<%= text_field_tag('navbar[][url]', com_module.url, id: nil, class: 'form-control', placeholder: '请输入资料下载地址') %>
</div>
<%= javascript_void_link '+', class: 'mt-1 btn btn-primary waves-effect waves-light btn-xs setBtn_s add_linkBtn' %>
<% end %>
</div>
</div>
<% else %>
<div class="row mt-2 align-items-center linkFormItem">
<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-label mt-1">
<input type="hidden" value="<%= com_module.module_type %>" name="navbar[][module_type]">
<%= text_field_tag('navbar[][name]', com_module.name, id: nil, class: 'form-control', placeholder: '请输入模块名称') %>
</div>
<div class="col-md-1 mt-1">
<%= text_field_tag('navbar[][position]', com_module.position, id: nil, class: 'form-control', placeholder: '位置') %>
</div>
<div class="col-md-3 mt-1">
<%= text_field_tag('navbar[][url]', com_module.url, id: nil, class: 'form-control', placeholder: '请输入资料下载地址') %>
</div>
<%= javascript_void_link '+', class: 'mt-1 btn btn-primary waves-effect waves-light btn-xs setBtn_s add_linkBtn' %>
<%= javascript_void_link '×', class: 'mt-1 btn btn-icon waves-effect btn-default waves-light setBtn_s ml10 del_linkBtn' %>
</div>
<% end %>
<% 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">&nbsp;</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">&nbsp;&nbsp;</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">&nbsp;&nbsp;</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 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">&nbsp;</label>-->
<!-- </label>-->
<!-- </div>-->
<!-- <div class="col-md-label mt-2">获奖证书</div>-->
<!-- </div>-->
<div class="error my-2 danger text-danger"></div>
<div id="requireForm">
<div class="row mt-2 mb-4 requireForm_item">
<div class="col-1 text-right">&nbsp;&nbsp;</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 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>
<% end %>
</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">&nbsp;</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">&nbsp;</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">&nbsp;</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 class="card mb-5">
<div class="card-header d-flex justify-content-between align-items-center">
<span>排行榜设置</span>
<a href="javascript:void(0)" class="btn btn-primary btn-custom waves-effect waves-light ml20" onclick="addNewTab();">+ 新增tab</a>
<span class="flex-1 text-right color-orange">实训ID填写示例实训地址为https://www.educoder.net/shixuns/u5plmgka/challenges则填写“u5plmgka”</span>
</div>
<div class="card-body">
<div id="large_panel" class="large_panel">
<div class="large_panel_part" attr_line="1">
<div class="row d-flex">
<span class="col-1 mt-2">tab标题</span>
<div class="col-2 no_padding">
<input type="text" class="form-control" name="tab_title_1"/>
</div>
<span class="col-1 text-right mt-2 no_padding">总排行榜占比:</span>
<div class="col-1 no_padding">
<input type="number" class="form-control" name="tab_percent_1"/>
</div><span class=" mt-2">%</span>
<div class="flex-1">
<a href="javascript:void(0)"class="btn btn-outline-primary export-action ml20 add_task_sub" onclick="add_task_sub(this)">新增子阶段</a>
<a href="javascript:void(0)" class="btn btn-outline-primary export-action ml20">发送短信提醒</a>
<a href="javascript:void(0)" class="btn btn-outline-primary export-action ml20">计算成绩</a>
</div>
<a href="javascript:void(0)" class="btn btn-default ml20" onclick="Del_tab(this)">删除</a>
<a href="javascript:void(0)" class="btn btn-outline-primary export-action ml20">保存</a>
</div>
<div id="small_panel_1" class="small_panel">
<div class="row d-flex small_panel_item" attr_line="sub_1_1" count="1">
<span class="col-1 mt-2 subName">第1阶段</span>
<div class="flex-1">
<div class="row">
<span class="mt-2 ml20">有效时间:</span>
<div class="col-2 no_padding input_middle">
<input class="use_time_begin_1_1 form-control" placeholder="有效开始时间"/>
</div>
<span class="mt-2">~</span>
<div class="col-2 no_padding input_middle">
<input class="use_time_end_1_1 form-control" placeholder="有效结束时间"/>
</div>
<span class="col-2 text-right mt-2 no_padding">任务完成要求:</span>
<div class="col-1 no_padding input_small">
<input type="number" class="form-control" name="task_require_small_1_1"/>
</div>
<span class="mt-2 ml10 mr10">/</span>
<div class="col-1 no_padding input_small">
<input type="number" class="form-control task_all" onchange="change_total(this)" name="task_require_all_1_1"/>
</div>
<span class=" mt-2">(总任务)</span>
<span class="col-1 text-right mt-2 no_padding">成绩来源:</span>
<div class="col-2 no_padding input_middle">
<select class="form-control" name="source_1_1">
<option>经验值</option>
<option>预测准确率</option>
</select>
</div>
</div>
<div class="row mt-2" id="task_Input_sub_1_1"></div>
</div>
<span>
<a href="javascript:void(0)" class="btn btn-default ml20 small_panel_item_del">删除</a>
</span>
</div>
</div>
<div class="col-md-label mt-2"><%= javascript_void_link '保存', class: 'btn btn-primary submit-btn' %></div>
</div>
</div>
</div>
</div>

@ -1,6 +1,6 @@
json.count @users.total_count
json.users do
json.array! @users.each do |user|
json.extract! user, :id, :login, :real_name, :identity, :school_name
json.extract! user, :id, :login, :real_name, :identity, :school_name, :hidden_phone
end
end

@ -33,14 +33,14 @@
<%= javascript_void_link('奖励', class: 'action reward-grade-action', data: { toggle: 'modal', target: '.admin-users-reward-grade-modal', id: user.id }) %>
<%= javascript_void_link '解锁', class: 'action unlock-action', data: { id: user.id, confirm: '确认解锁吗?' }, style: user.locked? ? '' : 'display: none;' %>
<%= javascript_void_link '解锁', class: 'action unlock-action', data: { id: user.id }, style: user.locked? ? '' : 'display: none;' %>
<% if user.registered? %>
<%= javascript_void_link '激活', class: 'action active-action', data: { id: user.id, confirm: '确认激活吗?' } %>
<%= javascript_void_link '激活', class: 'action active-action', data: { id: user.id } %>
<% end %>
<% if user.id != current_user.id %>
<%= javascript_void_link '加锁', class: 'action lock-action', data: { id: user.id, confirm: '确认加锁吗?' }, style: user.locked? || user.registered? ? 'display: none;' : '' %>
<%= javascript_void_link '加锁', class: 'action lock-action', data: { id: user.id }, style: user.locked? || user.registered? ? 'display: none;' : '' %>
<% end %>
<%= delete_link '删除', admins_user_path(user, element: ".user-item-#{user.id}"), class: 'delete-user-action' %>

@ -1,9 +1,11 @@
json.extract! @module, :id, :name, :position, :url, :md_edit
json.extract! @module, :id, :name, :position, :url
md = @module.competition_module_md_content
if md.present?
json.md_id md.id
json.md_name md.name
json.md_content md.content
json.competition_stage_id md.competition_stage_id
json.created_at md.created_at.strftime('%Y-%m-%d %H:%M:%S')
json.attachments do
json.array! md.attachments, partial: 'attachments/attachment_simple', as: :attachment

@ -1,5 +1,6 @@
json.count @all_count
json.personal @personal
json.competition_name @competition.name
json.competition_teams do
json.array! @all_teams&.each do |team|
json.extract! team, :id, :name, :invite_code

@ -1,6 +1,6 @@
json.count @users.total_count
json.users do
json.array! @users.each do |user|
json.extract! user, :id, :login, :real_name, :identity, :school_name
json.extract! user, :id, :login, :real_name, :identity, :school_name, :hidden_phone
end
end

@ -12,14 +12,15 @@
competitions/save_team_form:
attributes:
creator:
enrolled: "您已经报名过该竞赛了"
teacher_enroll_forbidden: "本竞赛的参赛者限定为:学生"
member_enroll_forbidden: "本竞赛的参赛者限定为:教师"
teacher_ids:
enroll_forbidden: "本竞赛的参赛者限定为:学生"
invalid_count: "教师数量应为%{minimum}~%{maximum}人"
enrolled: "教师 ${names} 已加入其它战队了"
enrolled: "教师 %{names} 已加入其它战队了"
member_ids:
enroll_forbidden: "本竞赛的参赛者限定为:教师"
invalid_count: "队员数量应为%{minimum}~%{maximum}人"
enrolled: "队员 ${names} 已加入其它战队了"
enrolled: "队员 %{names} 已加入其它战队了"

@ -1025,6 +1025,7 @@ Rails.application.routes.draw do
resources :competition_settings, only: [:index] do
post :basic_setting, on: :collection
post :nav_setting, on: :collection
end
resources :enroll_lists, only: [:index] do

@ -16,7 +16,7 @@ class MigrateCompetitionModuleType < ActiveRecord::Migration[5.2]
mod_type = "manual"
when '排行榜'
mod_type = "chart"
when '资料下载 '
when '资料下载'
mod_type = "resource"
else
mod_type = "md"

@ -0,0 +1,26 @@
class MigrateComModuleResource < ActiveRecord::Migration[5.2]
def change
Competition.all.each do |competition|
competition.competition_modules.each do |com_module|
mod_type = ""
case com_module.name.strip
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,5 @@
class MigrateCompetitionModuleManual < ActiveRecord::Migration[5.2]
def change
CompetitionModule.where(module_type: "manual").update_all(module_type: "md")
end
end

@ -0,0 +1,17 @@
class MigrateCompetitionModuleContent < ActiveRecord::Migration[5.2]
def change
Competition.all.each do |competition|
competition.informs.each do |inform|
if inform.status == 1
com_module = competition.competition_modules.find_by(module_type: "inform")
elsif inform.status == 2
com_module = competition.competition_modules.find_by(name: "参赛手册")
end
if com_module
new_md = CompetitionModuleMdContent.create!(competition_module_id: com_module.id, content: inform.description, name: inform.name)
Attachment.where(container_id: inform.id, container_type: "Inform").update_all(container_id: new_md.id, container_type: "CompetitionModuleMdContent")
end
end
end
end
end

@ -0,0 +1,14 @@
class MigrateCompetitionChartRules < ActiveRecord::Migration[5.2]
def change
add_column :competition_module_md_contents, :competition_stage_id, :integer, default: 0
ChartRule.all.each do |rule|
if rule.competition
com_module = rule.competition.competition_modules.find_by(module_type: "chart")
if com_module
CompetitionModuleMdContent.create!(content: rule.content, competition_module_id: com_module.id, competition_stage_id: rule.competition_stage_id ? rule.competition_stage_id : 0)
end
end
end
end
end

@ -0,0 +1,11 @@
class CreateCompetitionSchools < ActiveRecord::Migration[5.2]
def change
create_table :competition_schools do |t|
t.references :competition, index: true
t.references :school, index: true
t.string :source
t.timestamps
end
end
end

File diff suppressed because one or more lines are too long

@ -19161,6 +19161,362 @@ body[class*=jconfirm-no-scroll-] {
transform: scale(1);
}
/*!
* 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
*
*/
/* line 9, app/assets/stylesheets/bootstrap-datetimepicker.min.css */
.datetimepicker {
padding: 4px;
margin-top: 1px;
border-radius: 4px;
direction: ltr;
}
/* line 9, app/assets/stylesheets/bootstrap-datetimepicker.min.css */
.datetimepicker-inline {
width: 220px;
}
/* line 9, app/assets/stylesheets/bootstrap-datetimepicker.min.css */
.datetimepicker.datetimepicker-rtl {
direction: rtl;
}
/* line 9, app/assets/stylesheets/bootstrap-datetimepicker.min.css */
.datetimepicker.datetimepicker-rtl table tr td span {
float: right;
}
/* line 9, app/assets/stylesheets/bootstrap-datetimepicker.min.css */
.datetimepicker-dropdown, .datetimepicker-dropdown-left {
top: 0;
left: 0;
}
/* line 9, app/assets/stylesheets/bootstrap-datetimepicker.min.css */
[class*=" datetimepicker-dropdown"]:before {
content: '';
display: inline-block;
border-left: 7px solid transparent;
border-right: 7px solid transparent;
border-bottom: 7px solid #ccc;
border-bottom-color: rgba(0, 0, 0, 0.2);
position: absolute;
}
/* line 9, app/assets/stylesheets/bootstrap-datetimepicker.min.css */
[class*=" datetimepicker-dropdown"]:after {
content: '';
display: inline-block;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-bottom: 6px solid #fff;
position: absolute;
}
/* line 9, app/assets/stylesheets/bootstrap-datetimepicker.min.css */
[class*=" datetimepicker-dropdown-top"]:before {
content: '';
display: inline-block;
border-left: 7px solid transparent;
border-right: 7px solid transparent;
border-top: 7px solid #ccc;
border-top-color: rgba(0, 0, 0, 0.2);
border-bottom: 0;
}
/* line 9, app/assets/stylesheets/bootstrap-datetimepicker.min.css */
[class*=" datetimepicker-dropdown-top"]:after {
content: '';
display: inline-block;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-top: 6px solid #fff;
border-bottom: 0;
}
/* line 9, app/assets/stylesheets/bootstrap-datetimepicker.min.css */
.datetimepicker-dropdown-bottom-left:before {
top: -7px;
right: 6px;
}
/* line 9, app/assets/stylesheets/bootstrap-datetimepicker.min.css */
.datetimepicker-dropdown-bottom-left:after {
top: -6px;
right: 7px;
}
/* line 9, app/assets/stylesheets/bootstrap-datetimepicker.min.css */
.datetimepicker-dropdown-bottom-right:before {
top: -7px;
left: 6px;
}
/* line 9, app/assets/stylesheets/bootstrap-datetimepicker.min.css */
.datetimepicker-dropdown-bottom-right:after {
top: -6px;
left: 7px;
}
/* line 9, app/assets/stylesheets/bootstrap-datetimepicker.min.css */
.datetimepicker-dropdown-top-left:before {
bottom: -7px;
right: 6px;
}
/* line 9, app/assets/stylesheets/bootstrap-datetimepicker.min.css */
.datetimepicker-dropdown-top-left:after {
bottom: -6px;
right: 7px;
}
/* line 9, app/assets/stylesheets/bootstrap-datetimepicker.min.css */
.datetimepicker-dropdown-top-right:before {
bottom: -7px;
left: 6px;
}
/* line 9, app/assets/stylesheets/bootstrap-datetimepicker.min.css */
.datetimepicker-dropdown-top-right:after {
bottom: -6px;
left: 7px;
}
/* line 9, app/assets/stylesheets/bootstrap-datetimepicker.min.css */
.datetimepicker > div {
display: none;
}
/* line 9, app/assets/stylesheets/bootstrap-datetimepicker.min.css */
.datetimepicker.minutes div.datetimepicker-minutes {
display: block;
}
/* line 9, app/assets/stylesheets/bootstrap-datetimepicker.min.css */
.datetimepicker.hours div.datetimepicker-hours {
display: block;
}
/* line 9, app/assets/stylesheets/bootstrap-datetimepicker.min.css */
.datetimepicker.days div.datetimepicker-days {
display: block;
}
/* line 9, app/assets/stylesheets/bootstrap-datetimepicker.min.css */
.datetimepicker.months div.datetimepicker-months {
display: block;
}
/* line 9, app/assets/stylesheets/bootstrap-datetimepicker.min.css */
.datetimepicker.years div.datetimepicker-years {
display: block;
}
/* line 9, app/assets/stylesheets/bootstrap-datetimepicker.min.css */
.datetimepicker table {
margin: 0;
}
/* line 9, app/assets/stylesheets/bootstrap-datetimepicker.min.css */
.datetimepicker td, .datetimepicker th {
text-align: center;
width: 20px;
height: 20px;
border-radius: 4px;
border: 0;
}
/* line 9, app/assets/stylesheets/bootstrap-datetimepicker.min.css */
.table-striped .datetimepicker table tr td, .table-striped .datetimepicker table tr th {
background-color: transparent;
}
/* line 9, app/assets/stylesheets/bootstrap-datetimepicker.min.css */
.datetimepicker table tr td.minute:hover {
background: #eee;
cursor: pointer;
}
/* line 9, app/assets/stylesheets/bootstrap-datetimepicker.min.css */
.datetimepicker table tr td.hour:hover {
background: #eee;
cursor: pointer;
}
/* line 9, app/assets/stylesheets/bootstrap-datetimepicker.min.css */
.datetimepicker table tr td.day:hover {
background: #eee;
cursor: pointer;
}
/* line 9, app/assets/stylesheets/bootstrap-datetimepicker.min.css */
.datetimepicker table tr td.old, .datetimepicker table tr td.new {
color: #999;
}
/* line 9, app/assets/stylesheets/bootstrap-datetimepicker.min.css */
.datetimepicker table tr td.disabled, .datetimepicker table tr td.disabled:hover {
background: 0;
color: #999;
cursor: default;
}
/* line 9, app/assets/stylesheets/bootstrap-datetimepicker.min.css */
.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: -webkit-gradient(linear, left top, left bottom, from(#fdd49a), to(#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);
}
/* line 9, app/assets/stylesheets/bootstrap-datetimepicker.min.css */
.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;
}
/* line 9, app/assets/stylesheets/bootstrap-datetimepicker.min.css */
.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;
}
/* line 9, app/assets/stylesheets/bootstrap-datetimepicker.min.css */
.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: -webkit-gradient(linear, left top, left bottom, from(#08c), to(#04c));
background-image: linear-gradient(to bottom, #08c, #04c);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc',endColorstr='#0044cc',GradientType=0);
border-color: #04c #04c #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: #fff;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
}
/* line 9, app/assets/stylesheets/bootstrap-datetimepicker.min.css */
.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: #04c;
}
/* line 9, app/assets/stylesheets/bootstrap-datetimepicker.min.css */
.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: #039;
}
/* line 9, app/assets/stylesheets/bootstrap-datetimepicker.min.css */
.datetimepicker table tr td span {
display: block;
width: 23%;
height: 54px;
line-height: 54px;
float: left;
margin: 1%;
cursor: pointer;
border-radius: 4px;
}
/* line 9, app/assets/stylesheets/bootstrap-datetimepicker.min.css */
.datetimepicker .datetimepicker-hours span {
height: 26px;
line-height: 26px;
}
/* line 9, app/assets/stylesheets/bootstrap-datetimepicker.min.css */
.datetimepicker .datetimepicker-hours table tr td span.hour_am, .datetimepicker .datetimepicker-hours table tr td span.hour_pm {
width: 14.6%;
}
/* line 9, app/assets/stylesheets/bootstrap-datetimepicker.min.css */
.datetimepicker .datetimepicker-hours fieldset legend, .datetimepicker .datetimepicker-minutes fieldset legend {
margin-bottom: inherit;
line-height: 30px;
}
/* line 9, app/assets/stylesheets/bootstrap-datetimepicker.min.css */
.datetimepicker .datetimepicker-minutes span {
height: 26px;
line-height: 26px;
}
/* line 9, app/assets/stylesheets/bootstrap-datetimepicker.min.css */
.datetimepicker table tr td span:hover {
background: #eee;
}
/* line 9, app/assets/stylesheets/bootstrap-datetimepicker.min.css */
.datetimepicker table tr td span.disabled, .datetimepicker table tr td span.disabled:hover {
background: 0;
color: #999;
cursor: default;
}
/* line 9, app/assets/stylesheets/bootstrap-datetimepicker.min.css */
.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: -webkit-gradient(linear, left top, left bottom, from(#08c), to(#04c));
background-image: linear-gradient(to bottom, #08c, #04c);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc',endColorstr='#0044cc',GradientType=0);
border-color: #04c #04c #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: #fff;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
}
/* line 9, app/assets/stylesheets/bootstrap-datetimepicker.min.css */
.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: #04c;
}
/* line 9, app/assets/stylesheets/bootstrap-datetimepicker.min.css */
.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: #039;
}
/* line 9, app/assets/stylesheets/bootstrap-datetimepicker.min.css */
.datetimepicker table tr td span.old {
color: #999;
}
/* line 9, app/assets/stylesheets/bootstrap-datetimepicker.min.css */
.datetimepicker th.switch {
width: 145px;
}
/* line 9, app/assets/stylesheets/bootstrap-datetimepicker.min.css */
.datetimepicker th span.glyphicon {
pointer-events: none;
}
/* line 9, app/assets/stylesheets/bootstrap-datetimepicker.min.css */
.datetimepicker thead tr:first-child th, .datetimepicker tfoot th {
cursor: pointer;
}
/* line 9, app/assets/stylesheets/bootstrap-datetimepicker.min.css */
.datetimepicker thead tr:first-child th:hover, .datetimepicker tfoot th:hover {
background: #eee;
}
/* line 9, app/assets/stylesheets/bootstrap-datetimepicker.min.css */
.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;
}
/* BASICS */
/* line 3, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror {
@ -24796,68 +25152,93 @@ input.form-control {
}
/* line 37, app/assets/stylesheets/common.scss */
.font-20 {
font-size: 20px !important;
}
/* line 38, app/assets/stylesheets/common.scss */
.font-24 {
font-size: 24px !important;
}
/* line 39, app/assets/stylesheets/common.scss */
.padding10-5 {
padding: 10px 5px;
}
/* line 38, app/assets/stylesheets/common.scss */
/* line 40, app/assets/stylesheets/common.scss */
.width100 {
width: 100%;
}
/* line 39, app/assets/stylesheets/common.scss */
/* line 41, app/assets/stylesheets/common.scss */
.mb10 {
margin-bottom: 10px;
}
/* line 40, app/assets/stylesheets/common.scss */
/* line 42, app/assets/stylesheets/common.scss */
.mt10 {
margin-top: 10px;
}
/* line 41, app/assets/stylesheets/common.scss */
/* line 43, app/assets/stylesheets/common.scss */
.mr10 {
margin-right: 10px;
}
/* line 42, app/assets/stylesheets/common.scss */
/* line 44, app/assets/stylesheets/common.scss */
.ml10 {
margin-left: 10px;
}
/* line 44, app/assets/stylesheets/common.scss */
.ml20 {
margin-left: 20px;
}
/* line 45, app/assets/stylesheets/common.scss */
.textarea-width-100 {
width: 100%;
resize: none;
border: 1px solid #ccc;
}
/* line 43, app/assets/stylesheets/common.scss */
/* line 46, app/assets/stylesheets/common.scss */
.padding10 {
padding: 10px;
}
/* line 44, app/assets/stylesheets/common.scss */
/* line 47, app/assets/stylesheets/common.scss */
.padding5-10 {
padding: 5px 10px;
}
/* line 45, app/assets/stylesheets/common.scss */
/* line 48, app/assets/stylesheets/common.scss */
.position-r {
position: relative;
}
/* line 46, app/assets/stylesheets/common.scss */
/* line 49, app/assets/stylesheets/common.scss */
.color-grey-c {
color: #ccc;
}
/* line 47, app/assets/stylesheets/common.scss */
/* line 50, app/assets/stylesheets/common.scss */
.color-blue {
color: #4CACFF;
}
/* line 51, app/assets/stylesheets/common.scss */
.inline-block {
display: inline-block;
}
/* line 48, app/assets/stylesheets/common.scss */
/* line 52, app/assets/stylesheets/common.scss */
.hide {
display: none;
}
/* line 49, app/assets/stylesheets/common.scss */
/* line 53, app/assets/stylesheets/common.scss */
.show {
display: block;
}
@ -25171,6 +25552,47 @@ input.form-control {
background: #fff;
}
/* line 3, app/assets/stylesheets/admins/competition_settings.scss */
.admins-competition-settings-index-page .competition-mode-container .row {
height: 35px;
}
/* line 7, app/assets/stylesheets/admins/competition_settings.scss */
.admins-competition-settings-index-page .competition-mode-container .des-row {
height: auto;
}
/* line 11, app/assets/stylesheets/admins/competition_settings.scss */
.admins-competition-settings-index-page .competition-mode-container .form-control {
font-size: 14px;
}
/* line 22, app/assets/stylesheets/admins/competition_settings.scss */
.admins-competition-settings-index-page .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;
}
/* line 31, app/assets/stylesheets/admins/competition_settings.scss */
.admins-competition-settings-index-page .col-md-label-s {
-webkit-box-flex: 0;
flex: 0 0 30px;
padding-right: 15px;
padding-left: 15px;
position: relative;
}
/* line 38, app/assets/stylesheets/admins/competition_settings.scss */
.admins-competition-settings-index-page .setBtn_s {
height: 35px;
line-height: 5px;
}
/* line 4, app/assets/stylesheets/admins/cooperatives.scss */
.admins-cooperatives-index-page .coo-img-card .coo-img-item > .drag {
cursor: move;
@ -26059,7 +26481,7 @@ input.form-control {
flex: 3;
}
/* line 18, app/assets/stylesheets/admin.scss */
/* line 19, app/assets/stylesheets/admin.scss */
body {
width: 100vw;
height: 100vh;
@ -26074,28 +26496,28 @@ body {
overflow: hidden;
}
/* line 32, app/assets/stylesheets/admin.scss */
/* line 33, app/assets/stylesheets/admin.scss */
.simple_form .form-group .collection_radio_buttons {
margin-bottom: 0px;
}
/* line 36, app/assets/stylesheets/admin.scss */
/* line 37, app/assets/stylesheets/admin.scss */
.simple_form .form-group .form-check-inline {
height: calc(1.5em + 0.75rem + 2px);
}
/* line 42, app/assets/stylesheets/admin.scss */
/* line 43, app/assets/stylesheets/admin.scss */
input.form-control {
font-size: 14px;
}
/* line 46, app/assets/stylesheets/admin.scss */
/* line 47, app/assets/stylesheets/admin.scss */
.btn-default {
color: #666;
background: #e1e1e1 !important;
}
/* line 50, app/assets/stylesheets/admin.scss */
/* line 51, app/assets/stylesheets/admin.scss */
.export-absolute {
right: 20px;
position: absolute;

File diff suppressed because one or more lines are too long

@ -15788,68 +15788,93 @@ input.form-control {
}
/* line 37, app/assets/stylesheets/common.scss */
.font-20 {
font-size: 20px !important;
}
/* line 38, app/assets/stylesheets/common.scss */
.font-24 {
font-size: 24px !important;
}
/* line 39, app/assets/stylesheets/common.scss */
.padding10-5 {
padding: 10px 5px;
}
/* line 38, app/assets/stylesheets/common.scss */
/* line 40, app/assets/stylesheets/common.scss */
.width100 {
width: 100%;
}
/* line 39, app/assets/stylesheets/common.scss */
/* line 41, app/assets/stylesheets/common.scss */
.mb10 {
margin-bottom: 10px;
}
/* line 40, app/assets/stylesheets/common.scss */
/* line 42, app/assets/stylesheets/common.scss */
.mt10 {
margin-top: 10px;
}
/* line 41, app/assets/stylesheets/common.scss */
/* line 43, app/assets/stylesheets/common.scss */
.mr10 {
margin-right: 10px;
}
/* line 42, app/assets/stylesheets/common.scss */
/* line 44, app/assets/stylesheets/common.scss */
.ml10 {
margin-left: 10px;
}
/* line 44, app/assets/stylesheets/common.scss */
.ml20 {
margin-left: 20px;
}
/* line 45, app/assets/stylesheets/common.scss */
.textarea-width-100 {
width: 100%;
resize: none;
border: 1px solid #ccc;
}
/* line 43, app/assets/stylesheets/common.scss */
/* line 46, app/assets/stylesheets/common.scss */
.padding10 {
padding: 10px;
}
/* line 44, app/assets/stylesheets/common.scss */
/* line 47, app/assets/stylesheets/common.scss */
.padding5-10 {
padding: 5px 10px;
}
/* line 45, app/assets/stylesheets/common.scss */
/* line 48, app/assets/stylesheets/common.scss */
.position-r {
position: relative;
}
/* line 46, app/assets/stylesheets/common.scss */
/* line 49, app/assets/stylesheets/common.scss */
.color-grey-c {
color: #ccc;
}
/* line 47, app/assets/stylesheets/common.scss */
/* line 50, app/assets/stylesheets/common.scss */
.color-blue {
color: #4CACFF;
}
/* line 51, app/assets/stylesheets/common.scss */
.inline-block {
display: inline-block;
}
/* line 48, app/assets/stylesheets/common.scss */
/* line 52, app/assets/stylesheets/common.scss */
.hide {
display: none;
}
/* line 49, app/assets/stylesheets/common.scss */
/* line 53, app/assets/stylesheets/common.scss */
.show {
display: block;
}

@ -24796,68 +24796,93 @@ input.form-control {
}
/* line 37, app/assets/stylesheets/common.scss */
.font-20 {
font-size: 20px !important;
}
/* line 38, app/assets/stylesheets/common.scss */
.font-24 {
font-size: 24px !important;
}
/* line 39, app/assets/stylesheets/common.scss */
.padding10-5 {
padding: 10px 5px;
}
/* line 38, app/assets/stylesheets/common.scss */
/* line 40, app/assets/stylesheets/common.scss */
.width100 {
width: 100%;
}
/* line 39, app/assets/stylesheets/common.scss */
/* line 41, app/assets/stylesheets/common.scss */
.mb10 {
margin-bottom: 10px;
}
/* line 40, app/assets/stylesheets/common.scss */
/* line 42, app/assets/stylesheets/common.scss */
.mt10 {
margin-top: 10px;
}
/* line 41, app/assets/stylesheets/common.scss */
/* line 43, app/assets/stylesheets/common.scss */
.mr10 {
margin-right: 10px;
}
/* line 42, app/assets/stylesheets/common.scss */
/* line 44, app/assets/stylesheets/common.scss */
.ml10 {
margin-left: 10px;
}
/* line 44, app/assets/stylesheets/common.scss */
.ml20 {
margin-left: 20px;
}
/* line 45, app/assets/stylesheets/common.scss */
.textarea-width-100 {
width: 100%;
resize: none;
border: 1px solid #ccc;
}
/* line 43, app/assets/stylesheets/common.scss */
/* line 46, app/assets/stylesheets/common.scss */
.padding10 {
padding: 10px;
}
/* line 44, app/assets/stylesheets/common.scss */
/* line 47, app/assets/stylesheets/common.scss */
.padding5-10 {
padding: 5px 10px;
}
/* line 45, app/assets/stylesheets/common.scss */
/* line 48, app/assets/stylesheets/common.scss */
.position-r {
position: relative;
}
/* line 46, app/assets/stylesheets/common.scss */
/* line 49, app/assets/stylesheets/common.scss */
.color-grey-c {
color: #ccc;
}
/* line 47, app/assets/stylesheets/common.scss */
/* line 50, app/assets/stylesheets/common.scss */
.color-blue {
color: #4CACFF;
}
/* line 51, app/assets/stylesheets/common.scss */
.inline-block {
display: inline-block;
}
/* line 48, app/assets/stylesheets/common.scss */
/* line 52, app/assets/stylesheets/common.scss */
.hide {
display: none;
}
/* line 49, app/assets/stylesheets/common.scss */
/* line 53, app/assets/stylesheets/common.scss */
.show {
display: block;
}

@ -321,7 +321,7 @@ module.exports = {
},
compress: {
drop_debugger: true,
drop_console: true
drop_console: false
}
}
}),

@ -79,7 +79,7 @@ class CompetitionsIndex extends Component{
render() {
let {datas,page,count}=this.state;
console.log(this.props.current_user&&this.props.current_user.business)
return (
<div>
<div className="clearfix">

@ -1,6 +1,6 @@
import React, { Component } from 'react';
import { Breadcrumb,Layout,Table, Divider, Tag,Badge,Tooltip} from 'antd';
import { Link } from 'react-router-dom';
import axios from 'axios';
import NoneData from "../../courses/shixunHomework/shixunHomework";
@ -19,6 +19,18 @@ class Competitionteams extends Component{
componentDidMount(){
window.document.title = '竞赛';
if(this.props.match.params.identifier!=null){
let url=`/competitions/${this.props.match.params.identifier}/common_header.json`;
axios.get(url).then((response) => {
if(response.status===200){
this.setState({
data:response.data,
})
}
}).catch((error) => {
console.log(error)
})
}
this.getshixundata();
this.getcoursedata();
@ -131,7 +143,7 @@ class Competitionteams extends Component{
}
render() {
let {data}=this.state;
const shixuncolumns = [
{
title: '创建者',
@ -224,14 +236,14 @@ class Competitionteams extends Component{
];
console.log(this.state.shixundata)
// console.log(this.state.shixundata)
return (
<div className={"educontent clearfix mt20 "}>
<Breadcrumb separator=">">
<Breadcrumb.Item>全国高校计算机大赛战</Breadcrumb.Item>
<Breadcrumb.Item href="">报名</Breadcrumb.Item>
<Breadcrumb.Item href="">战队详情</Breadcrumb.Item>
<Breadcrumb.Item><Link to={"/newcompetitions"}>{data&&data.name}</Link></Breadcrumb.Item>
<Breadcrumb.Item><Link to={`/newcompetitions/${this.props.match.params.identifier}/enroll`}>报名</Link></Breadcrumb.Item>
<Breadcrumb.Item>战队详情</Breadcrumb.Item>
</Breadcrumb>
<Layout className={"teamsLayout"}>

@ -1,4 +1,5 @@
.teamsLayout{background: transparent !important;}
.teamsLayout .ant-layout-sider{
background: transparent !important;
flex: 0 0 180px !important;
@ -213,4 +214,126 @@
right: -5px;
width:93px;
top: 20px;
}
}
.Competitionthirdbox{
width:234px;
height:163px;
background:rgba(223,223,225,1);
}
.Competitionthirdbox{
width:234px;
height:163px;
background:rgba(223,223,225,1);
}
.Competitionthirdbox{
width:234px;
height:163px;
background:rgba(223,223,225,1);
position: relative;
}
.Competitionfirstbox{
width:233px;
height:167px;
background:rgba(255,231,160,1);
position: relative;
}
.Competitionsecondarybox{
width:234px;
height:155px;
background:rgba(253,230,217,1);
position: relative;
}
.rankingimg{
width: 60px;
height: 60px;
border-radius: 50% !important;
box-shadow: 0px 0px 12px rgba(0,0,0,0.2);
}
.Competitioncenter{
text-align: center;
padding-top: 20px;
}
.jinshaifont{
font-size: 16px;
color: rgba(5,16,26,1);
margin-top: 13px !important;
}
.Competitionthird .ant-card-body {
padding: 12px;
zoom: 1;
}
.Competitionthird .ant-card-meta-title{
margin-bottom: 0px !important;
}
.Competitionfirst .ant-card-body {
padding: 12px;
zoom: 1;
}
.Competitionsecondary .ant-card-body {
padding: 12px;
zoom: 1;
}
.center{
text-align: center;
}
.rankfonttop{
font-size:14px;
color:rgba(102,102,102,1);
}
.rankfontmid{
font-size:18px;
color:rgba(102,102,102,1);
}
.rankfontbottom{
font-size:26px;
color:rgba(165,91,41,1);
text-align: center;
}
.rankfontbottoms{
font-size:28px;
color:rgba(165,91,41,1);
text-align: center;
}
.Competitionuserimg{
width: 64px;
height: 63px;
border-radius: 50%;
}
.CompetitionsListzhezhao{
position: absolute;
top: 0px;
left: 0px;
width: 1206px;
height: 100%;
z-index: 10000;
display: none;
background: rgba(51, 51, 51,0.7);
text-align: center;
line-height: 416px;
color: #fff;
font-size: 50px;
}
.relative{position: relative;}
.relative:hover .CompetitionsListzhezhao{ display: block;}

@ -5,6 +5,7 @@ import axios from 'axios';
import {markdownToHTML,getImageUrl} from 'educoder';
import CompetitionContents from './CompetitionContents';
import CompetitionContentsChart from './CompetitionContentsChart';
import CompetitionContentsMd from './CompetitionContentsMd';
import NoneData from "../../courses/shixunHomework/shixunHomework";
import './CompetitionCommon.css';
@ -17,7 +18,9 @@ class CompetitionCommon extends Component{
this.state={
data:undefined,
bannerdata:undefined,
module_type:undefined
module_type:undefined,
mdContentdata:undefined,
Competitionedittype:false
}
}
@ -45,6 +48,7 @@ class CompetitionCommon extends Component{
if(response.status===200){
this.setState({
data:response.data,
thiskeys:response.data.competition_modules[0].position
})
this.getrightdata(
response.data.competition_modules[0].id,
@ -58,37 +62,83 @@ class CompetitionCommon extends Component{
})
}
getrightdatas=(e)=>{
let keys=parseInt(e.key);
this.getlistdata(keys)
}
getlistdata=(keys)=>{
let{data}=this.state;
this.setState({
thiskeys:keys
})
data&&data.competition_modules.map((item,key)=>{
if(keys===item.position){
this.getrightdata(item.id,item.module_type,item.module_url,item.has_url)
return
}
})
}
getrightdata=(id,typeid,module_url,has_url)=>{
console.log(id,typeid,module_url,has_url)
this.setState({
module_id:id,
module_type:typeid
})
let url=`${module_url}.json`;
axios.get(url).then((response) => {
if(response.status===200){
this.setState({
mdContent:response.data
if(typeid==="enroll"){
this.props.history.replace(`/newcompetitions/${this.props.match.params.identifier}/enroll`);
return
}
if(has_url===false){
let url=`${module_url}`;
axios.get(url).then((response) => {
if(response.status===200){
this.setState({
mdContentdata:response.data
})
}
}).catch((error) => {
console.log(error)
})
}
}).catch((error) => {
console.log(error)
}else{
this.props.history.replace(module_url);
return
}
}
Competitionedit=()=>{
this.setState({
Competitionedittype:true
})
}
hideCompetitionedit=()=>{
this.setState({
Competitionedittype:false
})
}
render() {
let {data,bannerdata,module_type,module_id,mdContent}=this.state;
let {data,bannerdata,module_type,Competitionedittype,mdContentdata}=this.state;
console.log(module_type)
return (
data===undefined?"":<div className={"educontent clearfix mt20 "}>
<Breadcrumb separator=">">
<Breadcrumb.Item href="">在线竞赛</Breadcrumb.Item>
<Breadcrumb.Item href="">{data&&data.name}</Breadcrumb.Item>
<Breadcrumb.Item><Link to={"/newcompetitions"}>在线竞赛</Link></Breadcrumb.Item>
<Breadcrumb.Item>{data&&data.name}</Breadcrumb.Item>
</Breadcrumb>
<div className={"mt10"}>
<div className={"mt10 relative"}>
<Row className={"CompetitionCommonbanner"}>
{data.competition_status==="nearly_published"?
this.props.current_user&&this.props.current_user.admin===true?"":this.props.current_user&&this.props.current_user.business===true?"":<div className={"CompetitionsListzhezhao"}>即将发布 敬请期待</div>:""}
<img className={"Commonimg"}
src={data.competition_status==="ended"?getImageUrl(`images/educoder/competitions/groups1.png`):data.competition_status==="nearly_published"?getImageUrl(`images/educoder/competitions/groups2.png`):data.competition_status==="progressing"?getImageUrl(`images/educoder/competitions/groups3.png`):""} />
<Col span={15}>
@ -155,7 +205,8 @@ class CompetitionCommon extends Component{
已结束
</Button>:
<Button type="primary" block className={"Competitionfontsize22"}>
<Link to={`/newcompetitions/${this.props.match.params.identifier}/enroll`}>立即报名</Link>
{data.competition_status==="nearly_published"?
this.props.current_user&&this.props.current_user.admin===true?<Link to={`/newcompetitions/${this.props.match.params.identifier}/enroll`}>立即报名</Link>:this.props.current_user&&this.props.current_user.business===true?<Link to={`/newcompetitions/${this.props.match.params.identifier}/enroll`}></Link>:<a></a>:<Link to={`/newcompetitions/${this.props.match.params.identifier}/enroll`}></Link>}
</Button>}
</Col>
<Col className={"mt10 Competitionfontsize16"}>{data&&data.enroll_end_time===null?"":`报名截止时间:${data&&data.enroll_end_time}`}</Col>
@ -165,12 +216,14 @@ class CompetitionCommon extends Component{
<Layout className={'teamsLayout mt40'}>
<Sider>
<Menu mode="inline" className="CompetitionMenu" defaultSelectedKeys={['1']}>
<Menu mode="inline" className="CompetitionMenu" defaultSelectedKeys={['1']} onClick={(e)=>this.getrightdatas(e)}>
{data&&data.competition_modules.map((item,key)=>{
return(
<Menu.Item key={item.position}>
{item.has_url===false?<span onClick={()=>this.getrightdata(item.id,item.module_type,item.module_url,item.has_url)}>{item.name}</span>:<a
{item.has_url===false?<span
// onClick={()=>this.getrightdata(item.id,item.module_type,item.module_url,item.has_url)}
>{item.name}</span>:<a
// target="_blank"
href={item.module_url}
// onClick={()=>this.getrightdata(item.id,item.module_type)}
@ -183,13 +236,25 @@ class CompetitionCommon extends Component{
</Sider>
<Layout className={"teamsLayoutleft"}>
{this.state.module_type==="chart"?<CompetitionContentsChart
{this.state.module_type==="chart"?Competitionedittype===false?<CompetitionContentsChart
{...this.props}
{...this.state}
Competitionedit={()=>this.Competitionedit()}
/>:"":Competitionedittype===false?<CompetitionContents
Competitionedit={()=>this.Competitionedit()}
{...this.props}
{...this.state}
/>:<CompetitionContents
/>:""}
{/*<CompetitionContentsChart*/}
{/*{...this.props}*/}
{/*{...this.state}*/}
{/*/>*/}
{Competitionedittype===true?<CompetitionContentsMd
hideCompetitionedit={()=>this.hideCompetitionedit()}
getlistdata={(keys)=>this.getlistdata(keys)}
{...this.props}
{...this.state}
/>}
/>:""}
</Layout>
</Layout>

@ -1,7 +1,7 @@
import React, { Component } from 'react';
import {Button,Layout} from 'antd';
import axios from 'axios';
import {markdownToHTML,getImageUrl} from 'educoder';
import {markdownToHTML,getImageUrl,AttachmentList} from 'educoder';
import NoneData from "../../courses/shixunHomework/shixunHomework";
const { Header, Footer, Sider, Content } = Layout;
@ -21,15 +21,22 @@ class CompetitionContents extends Component{
render() {
let{mdContent}=this.props;
let{mdContentdata}=this.props;
//
return (
<div className={"fr"}>
<Button className={"fr"} type="primary" ghost>
{this.props.current_user&&this.props.current_user.admin===true||this.props.current_user&&this.props.current_user.business===true?this.props.Competitionedittype===false?<Button className={"fr"} type="primary" ghost onClick={()=>this.props.Competitionedit()}>
编辑
</Button>
<Content className={"markdown-body"} dangerouslySetInnerHTML={{__html: markdownToHTML("").replace(/▁/g, "▁▁▁")}}>
</Content>
</Button>:"":""}
<div className={this.props.current_user&&this.props.current_user.admin===true||this.props.current_user&&this.props.current_user.business===true?"mt50 mb100":"mb100"}>
<Content className={"markdown-body"} dangerouslySetInnerHTML={{__html: markdownToHTML(mdContentdata===undefined?"":mdContentdata.md_content===undefined?"":mdContentdata.md_content).replace(/▁/g, "▁▁▁")}}>
</Content>
<div className={"mt30"}>
<AttachmentList {...this.props} {...this.state} attachments={mdContentdata===undefined?[]:mdContentdata.attachments===undefined?[]:mdContentdata.attachments}></AttachmentList>
</div>
</div>
</div>
)

@ -18,93 +18,75 @@ class CompetitionContents extends Component{
componentDidMount(){
window.document.title = '竞赛';
this.gettitledata()
}
gettitledata=()=>{
let url=`/competitions/${this.props.match.params.identifier}/chart_rules.json`;
axios.get(url)
.then((response) => {
console.log(response)
}).catch((error) => {
console.log(error)
})
}
render() {
const operations = <Icon type="form" />;
const operations = <Button className={"fr"} type="primary" ghost onClick={()=>this.props.Competitionedit()}>编辑</Button>;
const columns = [
{
title: 'Name',
dataIndex: 'name',
title: 'usersum',
dataIndex: 'usersum',
key: 'name',
render: text => <a>{text}</a>,
render: text => <a className={"color-blue"}>{text}</a>,
},
{
title: 'Age',
dataIndex: 'age',
key: 'age',
title: 'userimg',
dataIndex: 'userimg',
key: 'userimg',
render: text => <img className={"Competitionuserimg"} src={getImageUrl("images/avatars/User/60969?t=1569488691")}/>,
},
{
title: 'Address',
dataIndex: 'address',
key: 'address',
title: 'username',
dataIndex: 'username',
key: 'username',
render: text => <a>{text}</a>,
},
{
title: 'Tags',
key: 'tags',
dataIndex: 'tags',
render: tags => (
<span>
123123
</span>
),
title: 'school',
dataIndex: 'school',
key: 'school',
render: text => <a>{text}</a>,
},
{
title: 'Action',
key: 'action',
render: (text, record) => (
<span>
<a>Invite {record.name}</a>
<a>Delete</a>
</span>
),
title: 'spendtime',
dataIndex: 'spendtime',
key: 'spendtime',
render: text => <a>{text}</a>,
},
{
title: 'Values',
key: 'values',
dataIndex: 'values',
render: tags => (
<span>
123123
</span>
),
title: 'score',
dataIndex: 'score',
key: 'score',
render: text => <a className={"color-blue"}>{text}</a>,
},
];
const data = [
{
key: '1',
name: 'John Brown',
age: 32,
address: 'New York No. 1 Lake Park',
tags: ['nice', 'developer'],
values:123
},
{
key: '2',
name: 'Jim Green',
age: 42,
address: 'London No. 1 Lake Park',
tags: ['loser'],
values:123
},
{
key: '3',
name: 'Joe Black',
age: 32,
address: 'Sidney No. 1 Lake Park',
tags: ['cool', 'teacher'],
values:123
},
usersum: '1',
userimg: 'John Brown',
username: "小头鹰",
school: '吉首大学',
spendtime: '150000',
score:123123
}
];
return (
<div>
<Tabs tabBarExtraContent={operations}>
<Tabs tabBarExtraContent={this.props.current_user&&this.props.current_user.admin===true||this.props.current_user&&this.props.current_user.business===true?this.props.Competitionedittype===false?operations:"":""}>
<TabPane tab="总排行榜" key="1">
<Content className={"markdown-body"} dangerouslySetInnerHTML={{__html: markdownToHTML("Content of tab 1").replace(/▁/g, "▁▁▁")}}>
</Content>
@ -129,15 +111,27 @@ class CompetitionContents extends Component{
<Card
className={"Competitionthird"}
cover={
<img
alt="example"
src="https://gw.alipayobjects.com/zos/rmsportal/JiqGstEfoWAOHiTxclqi.png"
/>
<div className={"Competitionthirdbox center"}>
<li className="pr Competitioncenter">
<img src={getImageUrl("images/educoder/huangguan-two.png")}/>
<div className={"mt10"}>
<a href="/users/p45296381" className="color-dark">
<img className={"rankingimg"} src={getImageUrl("images/avatars/User/45459?t=1566570434")} />
<p className="task-hide rankName mt5 jinshaifont">蒙睿</p>
</a>
</div>
</li>
</div>
}
>
<Meta
title="Card title"
description="This is the description"
title={<div className={"center"}>
<div className={"rankfonttop"}>吉首大学</div>
<div className={"rankfontmid"}>78:01:02</div>
</div>}
description={
<div className={"rankfontbottom"}>3423.45</div>
}
/>
</Card>
</Col>
@ -145,32 +139,58 @@ class CompetitionContents extends Component{
<Card
className={"Competitionfirst"}
cover={
<img
alt="example"
src="https://gw.alipayobjects.com/zos/rmsportal/JiqGstEfoWAOHiTxclqi.png"
/>
<div className={"Competitionfirstbox center"}>
<li className="pr Competitioncenter">
<img src={getImageUrl("images/educoder/huangguan.png")}/>
<div className={"mt10"}>
<a href="/users/p37219480" className="color-dark">
<img className={"rankingimg"} src={getImageUrl("images/avatars/User/46128?t=1561087919")} />
<p className="task-hide rankName mt5 jinshaifont">李羿锟</p>
</a>
</div>
</li>
</div>
}
>
<Meta
title="Card title"
description="This is the description"
title={<div className={"center"}>
<div className={"rankfonttop"}>吉首大学</div>
<div className={"rankfontmid"}>78:01:02</div>
</div>}
description={
<div className={"rankfontbottoms"}>3423.45</div>
}
/>
</Card>
</Col>
<Col className="mt30" xs={{ span: 5, offset: 1 }} lg={{ span: 6, offset: 1 }}>
<Card
className={"Competitionsecondary"}
className={"Competitionsecondary "}
cover={
<img
alt="example"
src="https://gw.alipayobjects.com/zos/rmsportal/JiqGstEfoWAOHiTxclqi.png"
/>
<div className={"Competitionsecondarybox center"}>
<li className=" pr Competitioncenter ">
<img src={getImageUrl("images/educoder/huangguan-three.png")}/>
<div className={"mt10"}>
<a href="/users/p53601847" className="color-dark">
<img className={"rankingimg"} src={getImageUrl("images/avatars/User/26650?t=1561087884")} />
<p className="task-hide rankName mt5 jinshaifont">陈翊</p>
</a>
</div>
</li>
</div>
}
>
<Meta
title="Card title"
description="This is the description"
title={<div className={"center"}>
<div className={"rankfonttop"}>吉首大学</div>
<div className={"rankfontmid"}>78:01:02</div>
</div>}
description={
<div className={"rankfontbottom"}>3423.45</div>
}
/>
</Card>
</Col>

@ -0,0 +1,163 @@
import React, { Component } from 'react';
import {Button, Card, Row, Col ,Upload,Icon,message} from 'antd';
import axios from 'axios';
import {getImageUrl,getUrl,appendFileSizeToUploadFileAll,appendFileSizeToUploadFile} from 'educoder';
import TPMMDEditor from '../../tpm/challengesnew/TPMMDEditor';
class CompetitionContentsMd extends Component{
constructor(props) {
super(props)
this.contentMdRef = React.createRef();
this.state={
contentFileList:[]
}
}
componentDidMount(){
window.document.title = '竞赛';
let {mdContentdata}=this.props;
// this.gettitledata()
// is_pdf: false
//
let contentFileList = mdContentdata===undefined?[]:mdContentdata.attachments===undefined?[]:mdContentdata.attachments.map((item) => {
return {
id: item.id,
uid: item.id,
name: appendFileSizeToUploadFile(item),
url: item.url,
filesize: item.filesize,
status: 'done',
response:{id: item.id}
}
})
this.setState({
contentFileList:contentFileList
})
this.contentMdRef.current.setValue(mdContentdata===undefined?"":mdContentdata.md_content===undefined?"":mdContentdata.md_content || '')
}
handleContentUploadChange = (info) => {
let contentFileList = info.fileList;
this.setState({ contentFileList: appendFileSizeToUploadFileAll(contentFileList) });
}
onAttachmentRemove = (file, stateName) => {
debugger
if(file.response!=undefined){
this.props.confirm({
content: '是否确认删除?',
onOk: () => {
this.deleteAttachment(file, stateName)
},
onCancel() {
console.log('Cancel');
},
});
return false;
}
}
deleteAttachment = (file, stateName) => {
// 初次上传不能直接取uid
const url = `/attachments/${file.response ? file.response.id : file.uid}.json`
axios.delete(url, {
})
.then((response) => {
if (response.data) {
const { status } = response.data;
if (status == 0) {
console.log('--- success')
this.props.showNotification(response.data.message);
this.setState((state) => {
const index = state[stateName].indexOf(file);
const newFileList = state[stateName].slice();
newFileList.splice(index, 1);
return {
[stateName]: newFileList,
};
});
}
}
})
.catch(function (error) {
console.log(error);
});
}
handleSubmit = () => {
let {contentFileList}=this.state;
const mdContnet = this.contentMdRef.current.getValue().trim();
let attachment_ids = contentFileList.map(item => {
return item.response ? item.response.id : item.id
})
console.log(attachment_ids)
let url=`/competitions/${this.props.match.params.identifier}/update_md_content.json`;
axios.post(url,{
md_content_id:this.props.mdContentdata.md_id,
competition_module_id:this.props.mdContentdata.id,
content:mdContnet,
name:"编辑",
attachment_ids:attachment_ids
}
).then((response) => {
if(response.data.status===0){
this.props.showNotification(response.data.message);
this.props.getlistdata(this.props.thiskeys);
this.props.hideCompetitionedit();
}else{
this.props.showNotification(response.data.message);
}
}).catch((error) => {
console.log(error)
})
}
render() {
let {contentFileList}=this.state;
const uploadProps = {
width: 600,
fileList: contentFileList,
multiple: true,
// https://github.com/ant-design/ant-design/issues/15505
// showUploadList={false},然后外部拿到 fileList 数组自行渲染列表。
// showUploadList: false,
action: `${getUrl()}/api/attachments.json`,
onChange: this.handleContentUploadChange,
onRemove: (file) => this.onAttachmentRemove(file, 'contentFileList'),
beforeUpload: (file) => {
console.log('beforeUpload', file.name);
const isLt150M = file.size / 1024 / 1024 < 150;
if (!isLt150M) {
message.error('文件大小必须小于150MB!');
}
return isLt150M;
},
};
console.log(contentFileList)
return (
<div>
<TPMMDEditor ref={this.contentMdRef} placeholder="请输入任务内容说明最大限制5000个字符" mdID={'courseContentMD'} refreshTimeout={1500}
className="courseMessageMD" initValue={this.state.description}></TPMMDEditor>
<Upload {...uploadProps} className="upload_1 newWorkUpload">
<Button className="uploadBtn">
<Icon type="upload" /> 上传附件
</Button>
(单个文件150M以内)
</Upload>
<div className="clearfix mt30 mb30">
{/* htmlType="submit" */}
<Button type="primary" onClick={this.handleSubmit} className="defalutSubmitbtn fl mr20">提交</Button>
<a className="defalutCancelbtn fl" onClick={() => this.props.hideCompetitionedit()}>取消</ a>
</div>
</div>
)
}
}
export default CompetitionContentsMd;

@ -8,7 +8,7 @@ import Loading from '../../Loading';
import Loadable from 'react-loadable';
import { TPMIndexHOC } from '../tpm/TPMIndexHOC';
import { SnackbarHOC } from 'educoder';
import { CNotificationHOC } from '../courses/common/CNotificationHOC';
//新版竞赛首页
const CompetitionsIndex = Loadable({
@ -90,4 +90,4 @@ class Competitions extends Component {
}
}
export default SnackbarHOC() (TPMIndexHOC (Competitions)) ;
export default CNotificationHOC() (TPMIndexHOC (Competitions)) ;

@ -385,10 +385,7 @@ class GraduationTasksedit extends Component{
{description===undefined?"":
<div>
{/*<Form >*/}
{/* <Form >*/}
{/*内容*/}
<div className="stud-class-set bor-bottom-greyE pt20 pl20 pr20 pb0 edu-back-white">
<Form.Item label="类型">
@ -407,12 +404,12 @@ class GraduationTasksedit extends Component{
<style>
{
`
.yslgraduainputedit .ant-input{
border-right: none !important;
height: 40px !important;
}
`
.yslgraduainputedit .ant-input{
border-right: none !important;
height: 40px !important;
}
`
}
</style>
<Form.Item label="任务标题" >

@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe CompetitionSchool, type: :model do
pending "add some examples to (or delete) #{__FILE__}"
end
Loading…
Cancel
Save