commit
840ed71420
@ -0,0 +1,6 @@
|
||||
{
|
||||
"cells": [],
|
||||
"metadata": {},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"cells": [],
|
||||
"metadata": {},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
@ -1,426 +0,0 @@
|
||||
PATH
|
||||
remote: lib/gitlab-cli
|
||||
specs:
|
||||
gitlab (3.2.0)
|
||||
httparty
|
||||
terminal-table
|
||||
|
||||
GEM
|
||||
remote: https://gems.ruby-china.com/
|
||||
specs:
|
||||
aasm (5.0.5)
|
||||
concurrent-ruby (~> 1.0)
|
||||
actioncable (5.2.1)
|
||||
actionpack (= 5.2.1)
|
||||
nio4r (~> 2.0)
|
||||
websocket-driver (>= 0.6.1)
|
||||
actionmailer (5.2.1)
|
||||
actionpack (= 5.2.1)
|
||||
actionview (= 5.2.1)
|
||||
activejob (= 5.2.1)
|
||||
mail (~> 2.5, >= 2.5.4)
|
||||
rails-dom-testing (~> 2.0)
|
||||
actionpack (5.2.1)
|
||||
actionview (= 5.2.1)
|
||||
activesupport (= 5.2.1)
|
||||
rack (~> 2.0)
|
||||
rack-test (>= 0.6.3)
|
||||
rails-dom-testing (~> 2.0)
|
||||
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
||||
actionview (5.2.1)
|
||||
activesupport (= 5.2.1)
|
||||
builder (~> 3.1)
|
||||
erubi (~> 1.4)
|
||||
rails-dom-testing (~> 2.0)
|
||||
rails-html-sanitizer (~> 1.0, >= 1.0.3)
|
||||
active_decorator (1.2.0)
|
||||
activejob (5.2.1)
|
||||
activesupport (= 5.2.1)
|
||||
globalid (>= 0.3.6)
|
||||
activemodel (5.2.1)
|
||||
activesupport (= 5.2.1)
|
||||
activerecord (5.2.1)
|
||||
activemodel (= 5.2.1)
|
||||
activesupport (= 5.2.1)
|
||||
arel (>= 9.0)
|
||||
activestorage (5.2.1)
|
||||
actionpack (= 5.2.1)
|
||||
activerecord (= 5.2.1)
|
||||
marcel (~> 0.3.1)
|
||||
activesupport (5.2.1)
|
||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||
i18n (>= 0.7, < 2)
|
||||
minitest (~> 5.1)
|
||||
tzinfo (~> 1.1)
|
||||
acts-as-taggable-on (6.0.0)
|
||||
activerecord (~> 5.0)
|
||||
addressable (2.7.0)
|
||||
public_suffix (>= 2.0.2, < 5.0)
|
||||
archive-zip (0.11.0)
|
||||
io-like (~> 0.3.0)
|
||||
arel (9.0.0)
|
||||
autoprefixer-rails (9.6.1)
|
||||
execjs
|
||||
awesome_print (1.8.0)
|
||||
axlsx (3.0.0.pre)
|
||||
htmlentities (~> 4.3, >= 4.3.4)
|
||||
mimemagic (~> 0.3)
|
||||
nokogiri (~> 1.8, >= 1.8.2)
|
||||
rubyzip (~> 1.2, >= 1.2.1)
|
||||
axlsx_rails (0.5.2)
|
||||
actionpack (>= 3.1)
|
||||
axlsx (>= 2.0.1)
|
||||
bindex (0.5.0)
|
||||
bootsnap (1.3.1)
|
||||
msgpack (~> 1.0)
|
||||
bootstrap (4.3.1)
|
||||
autoprefixer-rails (>= 9.1.0)
|
||||
popper_js (>= 1.14.3, < 2)
|
||||
sassc-rails (>= 2.0.0)
|
||||
builder (3.2.3)
|
||||
bulk_insert (1.7.0)
|
||||
activerecord (>= 3.2.0)
|
||||
byebug (10.0.2)
|
||||
capybara (3.5.1)
|
||||
addressable
|
||||
mini_mime (>= 0.1.3)
|
||||
nokogiri (~> 1.8)
|
||||
rack (>= 1.6.0)
|
||||
rack-test (>= 0.6.3)
|
||||
xpath (~> 3.1)
|
||||
childprocess (0.9.0)
|
||||
ffi (~> 1.0, >= 1.0.11)
|
||||
chromedriver-helper (1.2.0)
|
||||
archive-zip (~> 0.10)
|
||||
nokogiri (~> 1.8)
|
||||
chunky_png (1.3.10)
|
||||
concurrent-ruby (1.0.5)
|
||||
connection_pool (2.2.2)
|
||||
crass (1.0.4)
|
||||
diff-lcs (1.3)
|
||||
diffy (3.3.0)
|
||||
elasticsearch (7.2.0)
|
||||
elasticsearch-api (= 7.2.0)
|
||||
elasticsearch-transport (= 7.2.0)
|
||||
elasticsearch-api (7.2.0)
|
||||
multi_json
|
||||
elasticsearch-transport (7.2.0)
|
||||
faraday
|
||||
multi_json
|
||||
enumerize (2.3.1)
|
||||
activesupport (>= 3.2)
|
||||
erubi (1.7.1)
|
||||
execjs (2.7.0)
|
||||
faraday (0.15.4)
|
||||
multipart-post (>= 1.2, < 3)
|
||||
ffi (1.9.25)
|
||||
font-awesome-sass (4.7.0)
|
||||
sass (>= 3.2)
|
||||
globalid (0.4.1)
|
||||
activesupport (>= 4.2.0)
|
||||
grape-entity (0.7.1)
|
||||
activesupport (>= 4.0)
|
||||
multi_json (>= 1.3.2)
|
||||
hashie (3.5.7)
|
||||
htmlentities (4.3.4)
|
||||
httparty (0.16.2)
|
||||
multi_xml (>= 0.5.2)
|
||||
i18n (1.1.0)
|
||||
concurrent-ruby (~> 1.0)
|
||||
io-like (0.3.0)
|
||||
jbuilder (2.7.0)
|
||||
activesupport (>= 4.2.0)
|
||||
multi_json (>= 1.2)
|
||||
jquery-rails (4.3.5)
|
||||
rails-dom-testing (>= 1, < 3)
|
||||
railties (>= 4.2.0)
|
||||
thor (>= 0.14, < 2.0)
|
||||
jwt (2.1.0)
|
||||
kaminari (1.1.1)
|
||||
activesupport (>= 4.1.0)
|
||||
kaminari-actionview (= 1.1.1)
|
||||
kaminari-activerecord (= 1.1.1)
|
||||
kaminari-core (= 1.1.1)
|
||||
kaminari-actionview (1.1.1)
|
||||
actionview
|
||||
kaminari-core (= 1.1.1)
|
||||
kaminari-activerecord (1.1.1)
|
||||
activerecord
|
||||
kaminari-core (= 1.1.1)
|
||||
kaminari-core (1.1.1)
|
||||
listen (3.1.5)
|
||||
rb-fsevent (~> 0.9, >= 0.9.4)
|
||||
rb-inotify (~> 0.9, >= 0.9.7)
|
||||
ruby_dep (~> 1.2)
|
||||
loofah (2.2.2)
|
||||
crass (~> 1.0.2)
|
||||
nokogiri (>= 1.5.9)
|
||||
mail (2.7.0)
|
||||
mini_mime (>= 0.1.1)
|
||||
marcel (0.3.2)
|
||||
mimemagic (~> 0.3.2)
|
||||
method_source (0.9.0)
|
||||
mimemagic (0.3.2)
|
||||
mini_mime (1.0.0)
|
||||
mini_portile2 (2.3.0)
|
||||
minitest (5.11.3)
|
||||
msgpack (1.2.4)
|
||||
multi_json (1.13.1)
|
||||
multi_xml (0.6.0)
|
||||
multipart-post (2.0.0)
|
||||
mustermann (1.0.3)
|
||||
mysql2 (0.5.2)
|
||||
nio4r (2.3.1)
|
||||
nokogiri (1.8.4)
|
||||
mini_portile2 (~> 2.3.0)
|
||||
oauth2 (1.4.1)
|
||||
faraday (>= 0.8, < 0.16.0)
|
||||
jwt (>= 1.0, < 3.0)
|
||||
multi_json (~> 1.3)
|
||||
multi_xml (~> 0.5)
|
||||
rack (>= 1.2, < 3)
|
||||
omniauth (1.9.0)
|
||||
hashie (>= 3.4.6, < 3.7.0)
|
||||
rack (>= 1.6.2, < 3)
|
||||
omniauth-oauth2 (1.6.0)
|
||||
oauth2 (~> 1.1)
|
||||
omniauth (~> 1.9)
|
||||
pdfkit (0.8.4.1)
|
||||
popper_js (1.14.5)
|
||||
public_suffix (4.0.1)
|
||||
puma (3.12.0)
|
||||
rack (2.0.5)
|
||||
rack-cors (1.0.2)
|
||||
rack-protection (2.0.5)
|
||||
rack
|
||||
rack-test (1.1.0)
|
||||
rack (>= 1.0, < 3)
|
||||
rails (5.2.1)
|
||||
actioncable (= 5.2.1)
|
||||
actionmailer (= 5.2.1)
|
||||
actionpack (= 5.2.1)
|
||||
actionview (= 5.2.1)
|
||||
activejob (= 5.2.1)
|
||||
activemodel (= 5.2.1)
|
||||
activerecord (= 5.2.1)
|
||||
activestorage (= 5.2.1)
|
||||
activesupport (= 5.2.1)
|
||||
bundler (>= 1.3.0)
|
||||
railties (= 5.2.1)
|
||||
sprockets-rails (>= 2.0.0)
|
||||
rails-dom-testing (2.0.3)
|
||||
activesupport (>= 4.2.0)
|
||||
nokogiri (>= 1.6)
|
||||
rails-html-sanitizer (1.0.4)
|
||||
loofah (~> 2.2, >= 2.2.2)
|
||||
rails-i18n (5.1.3)
|
||||
i18n (>= 0.7, < 2)
|
||||
railties (>= 5.0, < 6)
|
||||
railties (5.2.1)
|
||||
actionpack (= 5.2.1)
|
||||
activesupport (= 5.2.1)
|
||||
method_source
|
||||
rake (>= 0.8.7)
|
||||
thor (>= 0.19.0, < 2.0)
|
||||
rake (12.3.1)
|
||||
rb-fsevent (0.10.3)
|
||||
rb-inotify (0.9.10)
|
||||
ffi (>= 0.5.0, < 2)
|
||||
rchardet (1.8.0)
|
||||
redcarpet (3.4.0)
|
||||
redis (4.1.0)
|
||||
redis-actionpack (5.0.2)
|
||||
actionpack (>= 4.0, < 6)
|
||||
redis-rack (>= 1, < 3)
|
||||
redis-store (>= 1.1.0, < 2)
|
||||
redis-activesupport (5.0.7)
|
||||
activesupport (>= 3, < 6)
|
||||
redis-store (>= 1.3, < 2)
|
||||
redis-rack (2.0.5)
|
||||
rack (>= 1.5, < 3)
|
||||
redis-store (>= 1.2, < 2)
|
||||
redis-rails (5.0.2)
|
||||
redis-actionpack (>= 5.0, < 6)
|
||||
redis-activesupport (>= 5.0, < 6)
|
||||
redis-store (>= 1.2, < 2)
|
||||
redis-store (1.6.0)
|
||||
redis (>= 2.2, < 5)
|
||||
roo (2.8.2)
|
||||
nokogiri (~> 1)
|
||||
rubyzip (>= 1.2.1, < 2.0.0)
|
||||
roo-xls (1.2.0)
|
||||
nokogiri
|
||||
roo (>= 2.0.0, < 3)
|
||||
spreadsheet (> 0.9.0)
|
||||
rqrcode (0.10.1)
|
||||
chunky_png (~> 1.0)
|
||||
rqrcode_png (0.1.5)
|
||||
chunky_png
|
||||
rqrcode
|
||||
rspec-core (3.8.0)
|
||||
rspec-support (~> 3.8.0)
|
||||
rspec-expectations (3.8.1)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.8.0)
|
||||
rspec-mocks (3.8.0)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.8.0)
|
||||
rspec-rails (3.8.0)
|
||||
actionpack (>= 3.0)
|
||||
activesupport (>= 3.0)
|
||||
railties (>= 3.0)
|
||||
rspec-core (~> 3.8.0)
|
||||
rspec-expectations (~> 3.8.0)
|
||||
rspec-mocks (~> 3.8.0)
|
||||
rspec-support (~> 3.8.0)
|
||||
rspec-support (3.8.0)
|
||||
ruby-ole (1.2.12.2)
|
||||
ruby_dep (1.5.0)
|
||||
rubyzip (1.2.1)
|
||||
sass (3.5.7)
|
||||
sass-listen (~> 4.0.0)
|
||||
sass-listen (4.0.0)
|
||||
rb-fsevent (~> 0.9, >= 0.9.4)
|
||||
rb-inotify (~> 0.9, >= 0.9.7)
|
||||
sass-rails (5.0.7)
|
||||
railties (>= 4.0.0, < 6)
|
||||
sass (~> 3.1)
|
||||
sprockets (>= 2.8, < 4.0)
|
||||
sprockets-rails (>= 2.0, < 4.0)
|
||||
tilt (>= 1.1, < 3)
|
||||
sassc (2.0.1)
|
||||
ffi (~> 1.9)
|
||||
rake
|
||||
sassc-rails (2.1.2)
|
||||
railties (>= 4.0.0)
|
||||
sassc (>= 2.0)
|
||||
sprockets (> 3.0)
|
||||
sprockets-rails
|
||||
tilt
|
||||
searchkick (3.1.3)
|
||||
activemodel (>= 4.2)
|
||||
elasticsearch (>= 5)
|
||||
hashie
|
||||
selenium-webdriver (3.14.0)
|
||||
childprocess (~> 0.5)
|
||||
rubyzip (~> 1.2)
|
||||
sidekiq (5.2.7)
|
||||
connection_pool (~> 2.2, >= 2.2.2)
|
||||
rack (>= 1.5.0)
|
||||
rack-protection (>= 1.5.0)
|
||||
redis (>= 3.3.5, < 5)
|
||||
simple_form (4.1.0)
|
||||
actionpack (>= 5.0)
|
||||
activemodel (>= 5.0)
|
||||
simple_xlsx_reader (1.0.4)
|
||||
nokogiri
|
||||
rubyzip
|
||||
sinatra (2.0.5)
|
||||
mustermann (~> 1.0)
|
||||
rack (~> 2.0)
|
||||
rack-protection (= 2.0.5)
|
||||
tilt (~> 2.0)
|
||||
spreadsheet (1.2.3)
|
||||
ruby-ole (>= 1.0)
|
||||
spring (2.0.2)
|
||||
activesupport (>= 4.2)
|
||||
spring-watcher-listen (2.0.1)
|
||||
listen (>= 2.7, < 4.0)
|
||||
spring (>= 1.2, < 3.0)
|
||||
sprockets (3.7.2)
|
||||
concurrent-ruby (~> 1.0)
|
||||
rack (> 1, < 3)
|
||||
sprockets-rails (3.2.1)
|
||||
actionpack (>= 4.0)
|
||||
activesupport (>= 4.0)
|
||||
sprockets (>= 3.0.0)
|
||||
terminal-table (1.8.0)
|
||||
unicode-display_width (~> 1.1, >= 1.1.1)
|
||||
thor (0.20.0)
|
||||
thread_safe (0.3.6)
|
||||
tilt (2.0.8)
|
||||
turbolinks (5.2.0)
|
||||
turbolinks-source (~> 5.2)
|
||||
turbolinks-source (5.2.0)
|
||||
tzinfo (1.2.5)
|
||||
thread_safe (~> 0.1)
|
||||
uglifier (4.1.17)
|
||||
execjs (>= 0.3.0, < 3)
|
||||
unicode-display_width (1.4.0)
|
||||
web-console (3.6.2)
|
||||
actionview (>= 5.0)
|
||||
activemodel (>= 5.0)
|
||||
bindex (>= 0.4.0)
|
||||
railties (>= 5.0)
|
||||
websocket-driver (0.7.0)
|
||||
websocket-extensions (>= 0.1.0)
|
||||
websocket-extensions (0.1.3)
|
||||
wkhtmltopdf-binary (0.12.4)
|
||||
xpath (3.1.0)
|
||||
nokogiri (~> 1.8)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
aasm
|
||||
active_decorator
|
||||
acts-as-taggable-on (~> 6.0)
|
||||
awesome_print
|
||||
axlsx (~> 3.0.0.pre)
|
||||
axlsx_rails (~> 0.5.2)
|
||||
bootsnap (>= 1.1.0)
|
||||
bootstrap (~> 4.3.1)
|
||||
bulk_insert
|
||||
byebug
|
||||
capybara (>= 2.15, < 4.0)
|
||||
chromedriver-helper
|
||||
diffy
|
||||
enumerize
|
||||
faraday (~> 0.15.4)
|
||||
font-awesome-sass (= 4.7.0)
|
||||
gitlab!
|
||||
grape-entity (~> 0.7.1)
|
||||
jbuilder (~> 2.5)
|
||||
jquery-rails
|
||||
kaminari (~> 1.1, >= 1.1.1)
|
||||
listen (>= 3.0.5, < 3.2)
|
||||
mysql2 (>= 0.4.4, < 0.6.0)
|
||||
oauth2
|
||||
omniauth (~> 1.9.0)
|
||||
omniauth-oauth2 (~> 1.6.0)
|
||||
pdfkit
|
||||
puma (~> 3.11)
|
||||
rack-cors
|
||||
rails (~> 5.2.0)
|
||||
rails-i18n (~> 5.1)
|
||||
rchardet (~> 1.8)
|
||||
redcarpet (~> 3.4)
|
||||
redis-rails
|
||||
roo-xls
|
||||
rqrcode (~> 0.10.1)
|
||||
rqrcode_png
|
||||
rspec-rails (~> 3.8)
|
||||
ruby-ole
|
||||
rubyzip
|
||||
sass-rails (~> 5.0)
|
||||
searchkick
|
||||
selenium-webdriver
|
||||
sidekiq
|
||||
simple_form
|
||||
simple_xlsx_reader
|
||||
sinatra
|
||||
spreadsheet
|
||||
spring
|
||||
spring-watcher-listen (~> 2.0.0)
|
||||
turbolinks (~> 5)
|
||||
tzinfo-data
|
||||
uglifier (>= 1.3.0)
|
||||
web-console (>= 3.3.0)
|
||||
wkhtmltopdf-binary
|
||||
|
||||
RUBY VERSION
|
||||
ruby 2.3.7p456
|
||||
|
||||
BUNDLED WITH
|
||||
1.17.3
|
@ -0,0 +1,148 @@
|
||||
$(document).on('turbolinks:load', function() {
|
||||
if ($('body.cooperative-competitions-index-page').length > 0) {
|
||||
$('.modal.cooperative-upload-file-modal').on('upload:success', function(e, data){
|
||||
var $imageElement = $('.competition-image-' + data.source_id);
|
||||
$imageElement.attr('src', data.url);
|
||||
$imageElement.show();
|
||||
$imageElement.next().html('重新上传');
|
||||
});
|
||||
}
|
||||
|
||||
$(".cooperative-competition-list-form").on("change", '.competitions-hot-select', function () {
|
||||
var s_value = $(this).get(0).checked ? 1 : 0;
|
||||
var json = {};
|
||||
json["hot"] = s_value;
|
||||
$.ajax({
|
||||
url: "/cooperative/competitions/hot_setting",
|
||||
type: "POST",
|
||||
dataType:'json',
|
||||
data: json,
|
||||
success: function(){
|
||||
$.notify({ message: '操作成功' });
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// ============== 新增竞赛 ===============
|
||||
var $modal = $('.modal.cooperative-create-competition-modal');
|
||||
var $form = $modal.find('form.cooperative-create-competition-form');
|
||||
var $competitionNameInput = $form.find('input[name="competition_name"]');
|
||||
|
||||
$form.validate({
|
||||
errorElement: 'span',
|
||||
errorClass: 'danger text-danger',
|
||||
rules: {
|
||||
competition_name: {
|
||||
required: true
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// modal ready fire
|
||||
$modal.on('show.bs.modal', function () {
|
||||
$competitionNameInput.val('');
|
||||
});
|
||||
|
||||
$modal.on('click', '.submit-btn', function(){
|
||||
$form.find('.error').html('');
|
||||
|
||||
if ($form.valid()) {
|
||||
var url = $form.data('url');
|
||||
|
||||
$.ajax({
|
||||
method: 'POST',
|
||||
dataType: 'json',
|
||||
url: url,
|
||||
data: $form.serialize(),
|
||||
success: function(){
|
||||
$.notify({ message: '创建成功' });
|
||||
$modal.modal('hide');
|
||||
|
||||
setTimeout(function(){
|
||||
window.location.reload();
|
||||
}, 500);
|
||||
},
|
||||
error: function(res){
|
||||
var data = res.responseJSON;
|
||||
$form.find('.error').html(data.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// 导入学生
|
||||
var $importScoreModal = $('.modal.cooperative-import-competition-score-modal');
|
||||
var $importScoreForm = $importScoreModal.find('form.cooperative-import-competition-score-form');
|
||||
var $competitionIdInput = $importScoreForm.find('input[name="competition_id"]');
|
||||
|
||||
$importScoreModal.on('show.bs.modal', function(event){
|
||||
resetFileInputFunc($importScoreModal.find('.upload-file-input'));
|
||||
$importScoreModal.find('.file-names').html('选择文件');
|
||||
$importScoreModal.find('.upload-file-input').trigger('click');
|
||||
|
||||
var $link = $(event.relatedTarget);
|
||||
var competitionId = $link.data('competition-id');
|
||||
$competitionIdInput.val(competitionId);
|
||||
});
|
||||
|
||||
$importScoreModal.on('change', '.upload-file-input', function(e){
|
||||
var file = $(this)[0].files[0];
|
||||
$importScoreModal.find('.file-names').html(file ? file.name : '请选择文件');
|
||||
});
|
||||
|
||||
var importUserFormValid = function(){
|
||||
if($importScoreForm.find('input[name="file"]').val() == undefined || $importScoreForm.find('input[name="file"]').val().length == 0){
|
||||
$importScoreForm.find('.error').html('请选择文件');
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
var buildResultMessage = function(data){
|
||||
var messageHtml = "<div>导入结果:成功" + data.success + "条,失败"+ data.fail.length + "条</div>";
|
||||
|
||||
if(data.fail.length > 0){
|
||||
messageHtml += '<table class="table"><thead class="thead-light"><tr><th>数据</th><th>失败原因</th></tr></thead><tbody>';
|
||||
|
||||
data.fail.forEach(function(item){
|
||||
messageHtml += '<tr><td>' + item.data + '</td><td>' + item.message + '</td></tr>';
|
||||
});
|
||||
|
||||
messageHtml += '</tbody></table>'
|
||||
}
|
||||
|
||||
return messageHtml;
|
||||
};
|
||||
|
||||
$importScoreModal.on('click', '.submit-btn', function(){
|
||||
$importScoreForm.find('.error').html('');
|
||||
|
||||
if (importUserFormValid()) {
|
||||
$('body').mLoading({ text: '正在导入...' });
|
||||
|
||||
$.ajax({
|
||||
method: 'POST',
|
||||
dataType: 'json',
|
||||
url: '/cooperative/import_competition_scores',
|
||||
data: new FormData($importScoreForm[0]),
|
||||
processData: false,
|
||||
contentType: false,
|
||||
success: function(data){
|
||||
$('body').mLoading('destroy');
|
||||
$importScoreModal.modal('hide');
|
||||
|
||||
showMessageModal(buildResultMessage(data), function(){
|
||||
window.location.reload();
|
||||
});
|
||||
},
|
||||
error: function(res){
|
||||
$('body').mLoading('destroy');
|
||||
var data = res.responseJSON;
|
||||
$importScoreForm.find('.error').html(data.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -0,0 +1,9 @@
|
||||
$(document).on('turbolinks:load', function() {
|
||||
if($('body.cooperative-enroll-lists-index-page').length > 0){
|
||||
var search_form = $(".search-form");
|
||||
//导出
|
||||
$(".competition-enroll-list-form").on("click","#enroll-lists-export",function () {
|
||||
window.location.href = "/cooperative/competitions/"+$(this).attr("data-competition-id")+"/enroll_lists/export.xlsx?" + search_form.serialize();
|
||||
});
|
||||
}
|
||||
});
|
@ -0,0 +1,2 @@
|
||||
// Place all the behaviors and hooks related to the matching controller here.
|
||||
// All this logic will automatically be available in application.js.
|
@ -0,0 +1,2 @@
|
||||
// Place all the behaviors and hooks related to the matching controller here.
|
||||
// All this logic will automatically be available in application.js.
|
@ -0,0 +1,116 @@
|
||||
.cooperative-competition-settings-index-page {
|
||||
.competition-mode-container {
|
||||
.row {
|
||||
height: 35px;
|
||||
}
|
||||
|
||||
.des-row {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.form-control {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
//.mode-input {
|
||||
// input {
|
||||
// width: 40%;
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
.col-md-label{
|
||||
-webkit-box-flex: 0;
|
||||
flex: 0 0 10%;
|
||||
max-width: 10%;
|
||||
min-width: 30px;
|
||||
padding-right: 15px;
|
||||
padding-left: 15px;
|
||||
position: relative;
|
||||
}
|
||||
.col-md-label-s{
|
||||
-webkit-box-flex: 0;
|
||||
flex: 0 0 30px;
|
||||
padding-right: 15px;
|
||||
padding-left: 15px;
|
||||
position: relative;
|
||||
}
|
||||
.setBtn_s{
|
||||
height: 35px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.sponsor_label{
|
||||
border:1px solid #4CACFF;
|
||||
border-radius: 5px;
|
||||
background-color: rgba(76,172,255,0.3);
|
||||
color: #333;
|
||||
padding:0px 4px;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
float: left;
|
||||
margin: 4px 5px;
|
||||
|
||||
span{
|
||||
display: block;
|
||||
float: left;
|
||||
height: 28px;
|
||||
line-height: 28px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
a{
|
||||
font-size: 18px;
|
||||
float: left;
|
||||
height: 28px;
|
||||
line-height: 28px;
|
||||
}
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
|
||||
.task_Input_div:nth-child(3n-2) > span.col-4{
|
||||
flex: 0 0 81px;
|
||||
max-width: 81px;
|
||||
}
|
||||
.task_Input_div:nth-child(3n-2){
|
||||
flex: 0 0 50%;
|
||||
max-width: 50%;
|
||||
}
|
||||
.task_Input_div:nth-child(3n-1){
|
||||
flex: 0 0 25%;
|
||||
max-width: 25%;
|
||||
}
|
||||
.task_Input_div:nth-child(3n){
|
||||
flex: 0 0 25%;
|
||||
max-width: 25%;
|
||||
}
|
||||
.task_Input_div:nth-child(3n) > span.col-4{
|
||||
flex: 0 0 33.3%;
|
||||
max-width: 33.3%;
|
||||
}
|
||||
.task_Input_div:nth-child(3n) > div.col-6{
|
||||
flex: 0 0 50%;
|
||||
max-width: 50%;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
// Place all the styles related to the HackUserLastestCodes controller here.
|
||||
// They will automatically be included in application.css.
|
||||
// You can use Sass (SCSS) here: http://sass-lang.com/
|
@ -0,0 +1,3 @@
|
||||
// Place all the styles related to the hacks controller here.
|
||||
// They will automatically be included in application.css.
|
||||
// You can use Sass (SCSS) here: http://sass-lang.com/
|
@ -0,0 +1,51 @@
|
||||
class Cooperative::CompetitionPrizeUsersController < Cooperative::BaseController
|
||||
def index
|
||||
@competition = current_competition
|
||||
|
||||
prize_users = Admins::CompetitionPrizeUserQuery.call(params.merge(competition_id: current_competition.id))
|
||||
include_class = [:competition_team, :competition_prize, :approver,
|
||||
user: [:process_real_name_apply, :process_professional_apply, user_extension: :school]]
|
||||
@prize_users = paginate(prize_users.preload(include_class))
|
||||
|
||||
respond_to do |format|
|
||||
format.js
|
||||
format.html
|
||||
format.xlsx do
|
||||
@all_prize_users = prize_users
|
||||
filename = "#{@competition.name}竞赛获奖人信息列表_#{Time.current.strftime('%Y%m%d%H%M%S')}.xlsx"
|
||||
render xlsx: 'index', filename: filename
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
Admins::CreateCompetitionPrizeUsersService.call(current_competition)
|
||||
render_ok
|
||||
rescue ApplicationService::Error => ex
|
||||
render_error(ex.message)
|
||||
end
|
||||
|
||||
def approve
|
||||
Admins::ApproveCompetitionPrizeUserService.call(current_prize_user, current_user)
|
||||
@prize_user = current_prize_user
|
||||
rescue ApplicationService::Error => ex
|
||||
render_js_error(ex.message, type: :notify)
|
||||
end
|
||||
|
||||
def unapprove
|
||||
Admins::UnapproveCompetitionPrizeUserService.call(current_prize_user, current_user)
|
||||
@prize_user = current_prize_user
|
||||
rescue ApplicationService::Error => ex
|
||||
render_js_error(ex.message, type: :notify)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def current_prize_user
|
||||
@_current_prize_user ||= current_competition.competition_prize_users.find(params[:id])
|
||||
end
|
||||
|
||||
def current_competition
|
||||
@_current_competition ||= current_laboratory.competitions.find(params[:competition_id])
|
||||
end
|
||||
end
|
@ -0,0 +1,43 @@
|
||||
class Cooperative::CompetitionPrizesController < Cooperative::BaseController
|
||||
def index
|
||||
@competition = current_competition
|
||||
end
|
||||
|
||||
def new
|
||||
@prize = current_competition.competition_prizes.new
|
||||
end
|
||||
|
||||
def create
|
||||
@prize = current_competition.competition_prizes.create!(save_params)
|
||||
render_ok
|
||||
end
|
||||
|
||||
def edit
|
||||
@prize = current_competition_prize
|
||||
end
|
||||
|
||||
def update
|
||||
current_competition_prize.update!(save_params)
|
||||
render_ok
|
||||
end
|
||||
|
||||
def destroy
|
||||
current_competition_prize.destroy!
|
||||
|
||||
render_delete_success
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def current_competition_prize
|
||||
@_current_competition_prize ||= current_competition.competition_prizes.find(params[:id])
|
||||
end
|
||||
|
||||
def current_competition
|
||||
@_current_competition ||= current_laboratory.competitions.find(params[:competition_id])
|
||||
end
|
||||
|
||||
def save_params
|
||||
params.require(:competition_prize).permit(:name, :category, :num)
|
||||
end
|
||||
end
|
@ -0,0 +1,33 @@
|
||||
class Cooperative::CompetitionSettingsController < Cooperative::BaseController
|
||||
def index
|
||||
@competition = current_competition
|
||||
end
|
||||
|
||||
def basic_setting
|
||||
Admins::CompetitionBasicSettingService.call(current_competition, basic_form_params)
|
||||
render_ok
|
||||
end
|
||||
|
||||
def nav_setting
|
||||
Admins::CompetitionNavSettingService.call(current_competition, nav_form_params)
|
||||
render_ok
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def current_competition
|
||||
@_current_competition ||= current_laboratory.competitions.find(params[:competition_id])
|
||||
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, sponsor_schools: [], region_schools: [], manager_ids: [])
|
||||
end
|
||||
|
||||
def nav_form_params
|
||||
params.permit(:enroll_end_time,
|
||||
competition_staffs: %i[category minimum maximum mutiple_limited],
|
||||
navbar: %i[module_type module_id name hidden position url])
|
||||
end
|
||||
end
|
@ -0,0 +1,57 @@
|
||||
class Cooperative::CompetitionsController < Cooperative::BaseController
|
||||
before_action :find_competition, except: [:index]
|
||||
|
||||
def index
|
||||
# params[:sort_by] = params[:sort_by].presence || 'created_at'
|
||||
# params[:sort_direction] = params[:sort_direction].presence || 'desc'
|
||||
@competitions = current_laboratory.competitions.order("created_at desc")
|
||||
@params_page = params[:page] || 1
|
||||
@competitions = paginate @competitions
|
||||
ids = @competitions.map(&:id)
|
||||
@member_count_map = TeamMember.where(competition_id: ids).group(:competition_id).count
|
||||
|
||||
@competition_hot = ModuleSetting.exists?(module_type: "Competition", property: "hot")
|
||||
respond_to do |format|
|
||||
format.js
|
||||
format.html
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
name = params[:competition_name].to_s.strip
|
||||
Competition.create!(name: name)
|
||||
render_ok
|
||||
end
|
||||
|
||||
def hot_setting
|
||||
if params[:hot].to_i == 1 && !ModuleSetting.exists?(module_type: "Competition", property: "hot")
|
||||
ModuleSetting.create!(module_type: "Competition", property: "hot")
|
||||
elsif params[:hot].to_i == 0 && ModuleSetting.exists?(module_type: "Competition", property: "hot")
|
||||
ModuleSetting.where(module_type: "Competition", property: "hot").destroy_all
|
||||
end
|
||||
render_ok
|
||||
end
|
||||
|
||||
def publish
|
||||
@competition.update_attributes!(published_at: Time.now)
|
||||
end
|
||||
|
||||
def unpublish
|
||||
@competition.update_attributes!(published_at: nil)
|
||||
end
|
||||
|
||||
def online_switch
|
||||
if @competition.status
|
||||
@competition.update_attributes!(status: false)
|
||||
else
|
||||
@competition.update_attributes!(status: true, online_time: Time.now)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_competition
|
||||
@competition = current_laboratory.competitions.find_by(id: params[:id])
|
||||
end
|
||||
|
||||
end
|
@ -0,0 +1,33 @@
|
||||
class Cooperative::EnrollListsController < Cooperative::BaseController
|
||||
|
||||
def index
|
||||
@competition = current_competition
|
||||
default_sort('created_at', 'desc')
|
||||
enroll_lists = Admins::CompetitionEnrollListQuery.call(@competition, params)
|
||||
|
||||
@params_page = params[:page] || 1
|
||||
@enroll_lists = paginate enroll_lists.preload(competition_team: [:user, :teachers], user: { user_extension: :school })
|
||||
@personal = @competition.personal?
|
||||
|
||||
respond_to do |format|
|
||||
format.js
|
||||
format.html
|
||||
end
|
||||
end
|
||||
|
||||
def export
|
||||
default_sort('created_at', 'desc')
|
||||
@enroll_lists = Admins::CompetitionEnrollListQuery.call(current_competition, params)
|
||||
@enroll_lists = @enroll_lists.preload(competition_team: [:user, :teachers], user: { user_extension: :school })
|
||||
@competition_scores = current_competition.competition_scores.where(competition_stage_id: 0).order("score desc, cost_time desc").pluck(:competition_team_id)
|
||||
@personal = current_competition.personal?
|
||||
filename = ["#{current_competition.name}竞赛报名列表", Time.zone.now.strftime('%Y-%m-%d%H:%M:%S')].join('-') << '.xlsx'
|
||||
render xlsx: 'export', filename: filename
|
||||
end
|
||||
|
||||
private
|
||||
def current_competition
|
||||
@_current_competition ||= current_laboratory.competitions.find(params[:competition_id])
|
||||
end
|
||||
|
||||
end
|
@ -0,0 +1,180 @@
|
||||
class HacksController < ApplicationController
|
||||
before_action :require_login, except: [:index]
|
||||
before_action :require_teacher_identity, only: [:create, :edit, :update]
|
||||
before_action :require_auth_identity, only: [:update, :edit, :publish]
|
||||
before_action :find_hack, only: [:edit, :update, :publish, :start]
|
||||
|
||||
# 开启编程,如果第一次开启,创建一条记录,如果已经开启过的话,直接返回标识即可
|
||||
def start
|
||||
# 未发布的编程题,只能作者、或管理员访问
|
||||
start_hack_auth
|
||||
user_hack = @hack.hack_user_lastest_codes.mine(current_user.id)
|
||||
identifier =
|
||||
if user_hack.present?
|
||||
user_hack.identifier
|
||||
else
|
||||
user_identifier = generate_identifier HackUserLastestCode, 12
|
||||
user_code = {user_id: current_user.id, code: @hack.code,
|
||||
identifier: user_identifier, language: @hack.language}
|
||||
@hack.hack_user_lastest_codes.create!(user_code)
|
||||
user_identifier
|
||||
end
|
||||
render_ok(data: {identifier: identifier})
|
||||
end
|
||||
|
||||
# 首页
|
||||
def index
|
||||
# 筛选过滤与排序
|
||||
params_filter_or_order
|
||||
# 我解决的编程题数
|
||||
user_codes = HackUserLastestCode.mine(current_user).passed.joins(:hack)
|
||||
@simple_count = user_codes.where(hacks: {difficult: 1}).count
|
||||
@medium_count = user_codes.where(hacks: {difficult: 2}).count
|
||||
@diff_count = user_codes.where(hacks: {difficult: 3}).count
|
||||
@pass_count = @simple_count + @medium_count + @diff_count
|
||||
|
||||
@hacks_count = @hacks.count("hacks.id")
|
||||
@hacks = paginate @hacks
|
||||
end
|
||||
|
||||
def create
|
||||
begin
|
||||
logger.info("##########{hack_params}")
|
||||
hack = Hack.new(hack_params)
|
||||
ActiveRecord::Base.transaction do
|
||||
hack.user_id = current_user.id
|
||||
hack.identifier = generate_identifier Hack, 8
|
||||
hack.save!
|
||||
# 创建测试集与代码
|
||||
hack.hack_sets.create!(hack_sets_params)
|
||||
hack.hack_codes.create!(hack_code_params)
|
||||
end
|
||||
render_ok({identifier: hack.identifier})
|
||||
rescue Exception => e
|
||||
logger.error("########create_hack_error: #{e.message}")
|
||||
render_error("创建失败")
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
begin
|
||||
ActiveRecord::Base.transaction do
|
||||
@hack.update_attributes!(hack_params)
|
||||
set_ids = @hack.hack_sets.pluck(:id)
|
||||
# 更新
|
||||
param_update_sets params[:update_hack_sets], set_ids
|
||||
# 新建
|
||||
@hack.hack_sets.create!(hack_sets_params)
|
||||
# 更新代码
|
||||
@hack.hack_codes.create!(hack_code_params)
|
||||
end
|
||||
render_ok
|
||||
rescue Exception => e
|
||||
logger.error("####update_hack_error: #{e.message}")
|
||||
render_error("更新失败")
|
||||
end
|
||||
end
|
||||
|
||||
# 发布功能
|
||||
def publish
|
||||
@hack.update_attribute(:status, 1)
|
||||
render_ok
|
||||
end
|
||||
|
||||
# 发布列表
|
||||
def unpulished_list
|
||||
limit = params[:limit] || 16
|
||||
page = params[:page] || 1
|
||||
hacks = Hack.where(user_id: current_user.id, status: 0)
|
||||
@hacks_count = hacks.count
|
||||
@hacks = hacks.includes(:hack_sets).page(page).per(limit)
|
||||
end
|
||||
|
||||
def edit;end
|
||||
|
||||
private
|
||||
# 实名认证老师,管理员与运营人员权限
|
||||
def require_teacher_identity
|
||||
unless current_user.certification_teacher? || admin_or_business?
|
||||
tip_exception(403, "..")
|
||||
end
|
||||
end
|
||||
|
||||
# 只有自己,或者管理员才能更新
|
||||
def require_auth_identity
|
||||
unless @hack.user_id == current_user.id || admin_or_business?
|
||||
tip_exception(403, "..")
|
||||
end
|
||||
end
|
||||
|
||||
def find_hack
|
||||
@hack = Hack.find_by_identifier(params[:identifier])
|
||||
end
|
||||
|
||||
def hack_params
|
||||
params.require(:hack).permit(:name, :description, :difficult, :category, :open_or_not, :time_limit, :score)
|
||||
end
|
||||
|
||||
def hack_sets_params
|
||||
params.permit(hack_sets: [:input, :output, :position])[:hack_sets]
|
||||
end
|
||||
|
||||
def hack_code_params
|
||||
params.require(:hack_codes).permit(:code, :language)
|
||||
end
|
||||
|
||||
def publish_params
|
||||
params.require(:hack).permit(:difficult, :category, :open_or_not, :time_limit, :score)
|
||||
end
|
||||
|
||||
def param_update_sets sets, all_sets_id
|
||||
delete_set_ids = all_sets_id - sets.map{|set|set[:id]}
|
||||
@hack.hack_sets.where(id: delete_set_ids).destroy_all
|
||||
sets.each do |set|
|
||||
if all_sets_id.include?(set[:id])
|
||||
update_attrs = {input: set[:input], output: set[:output], position: set[:position]}
|
||||
@hack.hack_sets.find_by!(id: set[:id]).update_attributes(update_attrs)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def params_filter_or_order
|
||||
# 如果有来源,就不管发布公开私有
|
||||
select_sql = "hacks.*, if(hacks.hack_user_lastest_codes_count=0, 0, hacks.pass_num/hacks.hack_user_lastest_codes_count) passed_rate"
|
||||
if params[:come_from]
|
||||
hacks = Hack.select(select_sql).mine(current_user.id)
|
||||
else
|
||||
hacks = Hack.select(select_sql).published.opening
|
||||
end
|
||||
# 搜索
|
||||
if params[:search]
|
||||
hacks = hacks.where("name like ?", "%#{params[:search]}%")
|
||||
end
|
||||
# 难度
|
||||
if params[:difficult]
|
||||
hacks = hacks.where(difficult: params[:difficult])
|
||||
end
|
||||
# 状态
|
||||
if params[:status]
|
||||
user_hacks = HackUserLastestCode.where(user_id: current_user.id)
|
||||
if params[:status].to_i == -1
|
||||
if user_hacks.present?
|
||||
hacks = hacks.where.not(id: user_hacks.pluck(:hack_id))
|
||||
end
|
||||
else
|
||||
hacks = hacks.joins(:hack_user_lastest_code).where(hack_user_lastest_code: {status: params[:status]})
|
||||
end
|
||||
end
|
||||
# 排序
|
||||
sort_by = params[:sort_by] || "hack_user_lastest_codes_count"
|
||||
sort_direction = params[:sort_direction] || "desc"
|
||||
@hacks = hacks.order("#{sort_by} #{sort_direction}")
|
||||
end
|
||||
|
||||
def start_hack_auth
|
||||
return true if @hack == 1
|
||||
require_auth_identity
|
||||
end
|
||||
|
||||
|
||||
end
|
@ -0,0 +1,20 @@
|
||||
class Weapps::CreateCourseForm
|
||||
include ActiveModel::Model
|
||||
|
||||
attr_accessor :course
|
||||
attr_accessor :name, :course_list_name, :credit, :course_module_types
|
||||
|
||||
validates :name, presence: true
|
||||
validates :course_list_name, presence: true
|
||||
|
||||
validate :course_name_prefix
|
||||
validate :check_course_modules
|
||||
|
||||
def course_name_prefix
|
||||
raise '课堂名称应以课程名称开头' unless name.index(course_list_name) && name.index(course_list_name) == 0
|
||||
end
|
||||
|
||||
def check_course_modules
|
||||
raise '请至少添加一个课堂模块' if course_module_types.blank?
|
||||
end
|
||||
end
|
@ -0,0 +1,15 @@
|
||||
class Weapps::UpdateCourseForm
|
||||
include ActiveModel::Model
|
||||
|
||||
attr_accessor :course
|
||||
attr_accessor :name, :course_list_name, :credit
|
||||
|
||||
validates :name, presence: true
|
||||
validates :course_list_name, presence: true
|
||||
|
||||
validate :course_name_prefix
|
||||
|
||||
def course_name_prefix
|
||||
raise '课堂名称应以课程名称开头' unless name.index(course_list_name) && name.index(course_list_name) == 0
|
||||
end
|
||||
end
|
@ -0,0 +1,2 @@
|
||||
module HackUserLastestCodesHelper
|
||||
end
|
@ -0,0 +1,2 @@
|
||||
module HacksHelper
|
||||
end
|
@ -0,0 +1,3 @@
|
||||
class HackCode < ApplicationRecord
|
||||
# 编程题代码相关
|
||||
end
|
@ -0,0 +1,4 @@
|
||||
class HackSet < ApplicationRecord
|
||||
# 编程题测试集
|
||||
belongs_to :hack
|
||||
end
|
@ -0,0 +1,4 @@
|
||||
class HackUserCode < ApplicationRecord
|
||||
# 用户编程题的信息
|
||||
belongs_to :hack
|
||||
end
|
@ -0,0 +1,4 @@
|
||||
class HackUserDebug < ApplicationRecord
|
||||
belongs_to :hack
|
||||
belongs_to :hack_user_lastest_code
|
||||
end
|
@ -0,0 +1,217 @@
|
||||
class Subjects::CopySubjectService < ApplicationService
|
||||
attr_reader :subject, :to_subject, :user, :laboratory
|
||||
|
||||
def initialize(subject, user, laboratory=nil)
|
||||
@subject = subject
|
||||
@user = user
|
||||
@laboratory = laboratory
|
||||
subject_params = subject.attributes.dup.except('id', 'copy_subject_id', 'user_id', 'homepage_show')
|
||||
@to_subject = Subject.new(subject_params)
|
||||
end
|
||||
|
||||
def call
|
||||
return if subject.blank?
|
||||
ActiveRecord::Base.transaction do
|
||||
copy_subject!
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
# 复制实践课程表
|
||||
def copy_subject!
|
||||
to_subject.copy_subject_id = subject.id
|
||||
to_subject.user_id = user.id
|
||||
to_subject.save!
|
||||
|
||||
copy_stages_data!(subject, to_subject)
|
||||
copy_subject_members_data(to_subject)
|
||||
laboratory.laboratory_subjects.create(subject: to_subject) if laboratory
|
||||
end
|
||||
|
||||
# 复制章节需要的章节
|
||||
def copy_stages_data!(subject, to_subject)
|
||||
subject.stages.each do |stage|
|
||||
to_stage = to_subject.stages.new
|
||||
to_stage.attributes = stage.attributes.dup.except('id', 'subject_id', 'user_id')
|
||||
to_stage.user_id = user.id
|
||||
to_stage.save!
|
||||
|
||||
copy_stage_shixuns_data!(stage, to_stage)
|
||||
end
|
||||
end
|
||||
|
||||
# 创建实践课程关联实训表
|
||||
def copy_stage_shixuns_data!(stage, to_stage)
|
||||
stage.stage_shixuns.each do |stage_shixun|
|
||||
to_shixun = copy_shixun_data!(stage_shixun)
|
||||
to_stage_shixun = to_stage.stage_shixuns.new
|
||||
to_stage_shixun.attributes = stage_shixun.attributes.dup.except('id', 'subject_id', 'stage_id', 'shixun_id')
|
||||
to_stage_shixun.subject_id = to_stage.subject_id
|
||||
to_stage_shixun.shixun_id = to_shixun.id
|
||||
to_stage_shixun.save!
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
# 复制实训数据
|
||||
def copy_shixun_data!(stage_shixun)
|
||||
shixun = stage_shixun.shixun
|
||||
to_shixun = Shixun.new
|
||||
to_shixun.attributes = shixun.attributes.dup.except('id', 'user_id', 'identifier', 'homepage_show',
|
||||
'use_scope', 'averge_star', 'myshixuns_count')
|
||||
to_shixun.identifier = Util::UUID.generate_identifier(Shixun, 8)
|
||||
to_shixun.user_id = user.id
|
||||
if laboratory
|
||||
to_shixun.laboratory_id = laboratory.id
|
||||
end
|
||||
# 复制版本库
|
||||
fork_repository_name = "#{user.login}/#{to_shixun.identifier}"
|
||||
GitService.fork_repository(repo_path: "#{shixun.repo_name}.git",
|
||||
fork_repository_path: (fork_repository_name + ".git"))
|
||||
to_shixun.repo_name = fork_repository_name
|
||||
to_shixun.save!
|
||||
|
||||
copy_shixun_info_data!(shixun, to_shixun)
|
||||
copy_shixun_mirror_repositories_data!(shixun, to_shixun)
|
||||
copy_shixun_tag_repertoires_data!(shixun, to_shixun)
|
||||
copy_shixun_service_configs_data!(shixun, to_shixun)
|
||||
copy_challenges_data!(shixun, to_shixun)
|
||||
copy_shixun_members_data!(to_shixun)
|
||||
|
||||
# 云上实验室
|
||||
if laboratory
|
||||
laboratory.laboratory_shixuns.create(shixun: to_shixun)
|
||||
end
|
||||
to_shixun
|
||||
end
|
||||
|
||||
# 创建实训长字段内容
|
||||
def copy_shixun_info_data!(shixun, to_shixun)
|
||||
to_shixun_info = ShixunInfo.new
|
||||
to_shixun_info.attributes = shixun.shixun_info.attributes.except('id', 'shixun_id')
|
||||
to_shixun_info.shixun_id = to_shixun.id
|
||||
to_shixun_info.save!
|
||||
end
|
||||
|
||||
# 创建实训镜像标签
|
||||
def copy_shixun_mirror_repositories_data!(shixun, to_shixun)
|
||||
shixun.shixun_mirror_repositories.each do |shixun_mirror_repository|
|
||||
to_shixun_mirror_repository = to_shixun.shixun_mirror_repositories.new
|
||||
to_shixun_mirror_repository.attributes = shixun_mirror_repository.attributes.dup.except('id', 'shixun_id')
|
||||
to_shixun_mirror_repository.shixun_id = to_shixun.id
|
||||
to_shixun_mirror_repository.save!
|
||||
end
|
||||
end
|
||||
|
||||
# 创建实训tag标签
|
||||
def copy_shixun_tag_repertoires_data!(shixun, to_shixun)
|
||||
shixun.shixun_tag_repertoires.each do |shixun_tag_repertoire|
|
||||
to_shixun_tag_repertoire = to_shixun.shixun_tag_repertoires.new
|
||||
to_shixun_tag_repertoire.attributes = shixun_tag_repertoire.attributes.dup.except('id', 'shixun_id')
|
||||
to_shixun_tag_repertoire.shixun_id = to_shixun.id
|
||||
to_shixun_tag_repertoire.save!
|
||||
end
|
||||
end
|
||||
|
||||
# 复制实训服务配置
|
||||
def copy_shixun_service_configs_data!(shixun, to_shixun)
|
||||
shixun.shixun_service_configs.each do |shixun_service_config|
|
||||
to_shixun_service_config = to_shixun.shixun_service_configs.new
|
||||
to_shixun_service_config.attributes = shixun_service_config.attributes.dup.except('id', 'shixun_id')
|
||||
to_shixun_service_config.shixun_id = to_shixun.id
|
||||
to_shixun_service_config.save!
|
||||
end
|
||||
end
|
||||
|
||||
# 复制关卡信息
|
||||
def copy_challenges_data!(shixun, to_shixun)
|
||||
shixun.challenges.each do |challenge|
|
||||
to_challenge = to_shixun.challenges.new
|
||||
to_challenge.attributes = challenge.attributes.dup.except('id', 'shixun_id', 'praises_count', 'user_id', 'visits')
|
||||
to_challenge.user_id = user.id
|
||||
to_challenge.shixun_id = to_shixun.id
|
||||
to_challenge.save!
|
||||
|
||||
copy_challenge_answers_data!(challenge, to_challenge)
|
||||
copy_challenge_tags_data!(challenge, to_challenge)
|
||||
copy_test_sets_data!(challenge, to_challenge)
|
||||
copy_challenge_chooses_data!(challenge, to_challenge)
|
||||
end
|
||||
end
|
||||
|
||||
# 复制答案数据
|
||||
def copy_challenge_answers_data!(challenge, to_challenge)
|
||||
challenge.challenge_answers.each do |challenge_answer|
|
||||
to_challenge_answer = to_challenge.challenge_answers.new
|
||||
to_challenge_answer.attributes = challenge_answer.attributes.dup.except('id', 'challenge_id')
|
||||
to_challenge_answer.challenge_id = to_challenge.id
|
||||
to_challenge_answer.save!
|
||||
end
|
||||
end
|
||||
|
||||
# 复制关卡标签数据
|
||||
def copy_challenge_tags_data!(challenge, to_challenge)
|
||||
challenge.challenge_tags.each do |challenge_tag|
|
||||
to_challenge_tag = to_challenge.challenge_tags.new
|
||||
to_challenge_tag.attributes = challenge_tag.attributes.dup.except('id', 'challenge_id')
|
||||
to_challenge_tag.challenge_id = to_challenge.id
|
||||
to_challenge_tag.save!
|
||||
end
|
||||
end
|
||||
|
||||
# 复制测试集
|
||||
def copy_test_sets_data!(challenge, to_challenge)
|
||||
challenge.test_sets.each do |test_set|
|
||||
to_test_set = to_challenge.test_sets.new
|
||||
to_test_set.attributes = test_set.attributes.dup.except('id', 'challenge_id')
|
||||
to_test_set.challenge_id = to_challenge.id
|
||||
to_test_set.save!
|
||||
end
|
||||
end
|
||||
|
||||
# 复制选择题关卡
|
||||
def copy_challenge_chooses_data!(challenge, to_challenge)
|
||||
challenge.challenge_chooses.each do |challenge_choose|
|
||||
to_challenge_choose = to_challenge.challenge_chooses.new
|
||||
to_challenge_choose.attributes = challenge_choose.attributes.dup.except('id', 'challenge_id')
|
||||
to_challenge_choose.challenge_id = to_challenge.id
|
||||
to_challenge_choose.save!
|
||||
|
||||
copy_challenge_questions_data!(challenge_choose, to_challenge_choose)
|
||||
copy_challenge_choose_tags_data!(challenge_choose, to_challenge_choose)
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
# 复制选择题问题
|
||||
def copy_challenge_questions_data!(challenge_choose, to_challenge_choose)
|
||||
challenge_choose.challenge_questions.each do |challenge_question|
|
||||
to_challenge_question = to_challenge_choose.challenge_questions.new
|
||||
to_challenge_question.attributes = challenge_question.attributes.dup.except('id', 'challenge_choose_id')
|
||||
to_challenge_question.challenge_choose_id = to_challenge_choose.id
|
||||
to_challenge_question.save!
|
||||
end
|
||||
end
|
||||
|
||||
# 复制选择题标签
|
||||
def copy_challenge_choose_tags_data!(challenge_choose, to_challenge_choose)
|
||||
challenge_choose.challenge_tags.each do |challenge_tag|
|
||||
to_challenge_tag = to_challenge_choose.challenge_tags.new
|
||||
to_challenge_tag.attributes = challenge_tag.attributes.dup.except('id', 'challenge_choose_id')
|
||||
to_challenge_tag.challenge_choose_id = to_challenge_choose.id
|
||||
to_challenge_tag.save!
|
||||
end
|
||||
end
|
||||
|
||||
# 创建实训成员
|
||||
def copy_shixun_members_data!(to_shixun)
|
||||
to_shixun.shixun_members.create!(user_id: user.id, role: 1)
|
||||
end
|
||||
|
||||
# 创建课程成员
|
||||
def copy_subject_members_data(to_subject)
|
||||
to_subject.subject_members.create!(user_id: user.id, role: 1)
|
||||
end
|
||||
|
||||
end
|
@ -0,0 +1,37 @@
|
||||
class Weapps::CreateCourseService < ApplicationService
|
||||
attr_reader :course, :params
|
||||
|
||||
def initialize(course, params)
|
||||
@course = course
|
||||
@params = params
|
||||
end
|
||||
|
||||
def call
|
||||
Weapps::CreateCourseForm.new(form_params).validate!
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
course.name = params[:name].to_s.strip
|
||||
course.school_id = course.teacher&.school_id
|
||||
course.is_public = 0
|
||||
course.credit = params[:credit].blank? ? nil : params[:credit]
|
||||
course_list = CourseList.find_by(name: params[:course_list_name].to_s.strip)
|
||||
if course_list
|
||||
course.course_list_id = course_list.id
|
||||
else
|
||||
new_course_list = CourseList.create!(name: params[:course_list_name].to_s.strip, user_id: course.tea_id, is_admin: 0)
|
||||
course.course_list_id = new_course_list.id
|
||||
end
|
||||
course.save!
|
||||
|
||||
course.generate_invite_code
|
||||
CourseMember.create!(course_id: course.id, user_id: course.tea_id, role: 1)
|
||||
course.create_course_modules(params[:course_module_types])
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def form_params
|
||||
params.merge(course: course)
|
||||
end
|
||||
end
|
@ -0,0 +1,31 @@
|
||||
class Weapps::UpdateCourseService < ApplicationService
|
||||
attr_reader :course, :params
|
||||
|
||||
def initialize(course, params)
|
||||
@course = course
|
||||
@params = params
|
||||
end
|
||||
|
||||
def call
|
||||
Weapps::UpdateCourseForm.new(form_params).validate!
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
course.name = params[:name].to_s.strip
|
||||
course.credit = params[:credit].blank? ? nil : params[:credit]
|
||||
course_list = CourseList.find_by(name: params[:course_list_name].to_s.strip)
|
||||
if course_list
|
||||
course.course_list_id = course_list.id
|
||||
else
|
||||
new_course_list = CourseList.create!(name: params[:course_list_name].to_s.strip, user_id: course.tea_id, is_admin: 0)
|
||||
course.course_list_id = new_course_list.id
|
||||
end
|
||||
course.save!
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def form_params
|
||||
params.merge(course: course)
|
||||
end
|
||||
end
|
@ -0,0 +1 @@
|
||||
$('.competition-prize-user-list-container .competition-prize-user-item-<%= @prize_user.id %>').html("<%= j( render partial: 'cooperative/competition_prize_users/shared/tr', locals: { prize_user: @prize_user } ) %>");
|
@ -0,0 +1,64 @@
|
||||
<%
|
||||
define_breadcrumbs do
|
||||
add_breadcrumb('竞赛列表', cooperative_competitions_path)
|
||||
add_breadcrumb(@competition.name)
|
||||
end
|
||||
%>
|
||||
|
||||
<div class="box search-form-container flex-column mb-0 pb-0 competition-prize-user-form">
|
||||
<ul class="nav nav-tabs w-100 search-form-tabs">
|
||||
<li class="nav-item">
|
||||
<%= link_to '报名列表', cooperative_competition_enroll_lists_path(@competition), class: "nav-link search-form-tab" %>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<%= link_to '获奖证书审批', cooperative_competition_competition_prize_users_path(@competition), class: "nav-link search-form-tab active" %>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="d-flex">
|
||||
<%= form_tag(cooperative_competition_competition_prize_users_path(unsafe_params), method: :get, class: 'search-form mt-3 flex-1 d-flex align-items-end', remote: true) do %>
|
||||
<div class="form-group mb-0 mr-3">
|
||||
<label for="status">奖项:</label>
|
||||
<% prize_options = [['不限', '']] + @competition.competition_prizes.map{ |p| [p.name, p.id] } %>
|
||||
<%= select_tag(:prize_id, options_for_select(prize_options), class: 'form-control') %>
|
||||
</div>
|
||||
|
||||
<% auth_options = [['不限', ''], %w(未认证 not_authed), %w(待认证 authing), %w(已认证 authed)] %>
|
||||
<div class="form-group mb-0 mr-3">
|
||||
<label for="status">实名认证状态:</label>
|
||||
<%= select_tag(:real_name_auth, options_for_select(auth_options), class: 'form-control') %>
|
||||
</div>
|
||||
<div class="form-group mb-0 mr-3">
|
||||
<label for="status">职业认证状态:</label>
|
||||
<%= select_tag(:professional_auth, options_for_select(auth_options), class: 'form-control') %>
|
||||
</div>
|
||||
|
||||
<div class="form-group mb-0 mr-3">
|
||||
<label for="status">职业:</label>
|
||||
<%- identity_options = [['不限', ''], %w(教师 0), %w(学生 1)] %>
|
||||
<%= select_tag(:identity, options_for_select(identity_options), class: 'form-control') %>
|
||||
</div>
|
||||
|
||||
<div class="form-group mb-0 mr-3">
|
||||
<label for="status">审批状态:</label>
|
||||
<%- status_options = [['不限', ''], %w(未审批 pending), %w(已审批 approved)] %>
|
||||
<%= select_tag(:status, options_for_select(status_options), class: 'form-control') %>
|
||||
</div>
|
||||
|
||||
<%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-sm-2 ml-3', placeholder: '战队/学校名称检索') %>
|
||||
|
||||
<%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %>
|
||||
<%= link_to '清除', cooperative_competition_competition_prize_users_path(@competition), class: "btn btn-default",'data-disable-with': '清除中...' %>
|
||||
<% end %>
|
||||
|
||||
<div class="mt-3 d-flex align-items-end">
|
||||
<%= link_to '导出', cooperative_competition_competition_prize_users_path(competition_id: @competition.id, format: :xlsx), class: 'btn btn-primary' %>
|
||||
<%#= javascript_void_link '导出', class: 'btn btn-primary', 'data-url': cooperative_competition_competition_prize_users_path(competition_id: @competition.id, format: :xlsx) %>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="box cooperative-list-container competition-prize-user-list-container">
|
||||
<%= render(partial: 'cooperative/competition_prize_users/shared/list', locals: { prize_users: @prize_users }) %>
|
||||
</div>
|
@ -0,0 +1 @@
|
||||
$('.competition-prize-user-list-container').html("<%= j( render partial: 'cooperative/competition_prize_users/shared/list', locals: { prize_users: @prize_users } ) %>");
|
@ -0,0 +1,33 @@
|
||||
wb = xlsx_package.workbook
|
||||
|
||||
wb.styles do |s|
|
||||
blue_cell = s.add_style :bg_color => "FAEBDC", :sz => 10,:height => 25,:b => true, :border => { :style => :thin, :color =>"000000" },:alignment => {wrap_text: true,:horizontal => :center,:vertical => :center}
|
||||
wb.add_worksheet(name: "#{@competition.name}证书审批列表") do |sheet|
|
||||
sheet.add_row %w(序号 排名 奖项 战队ID 战队名称 姓名 职业 学号 学校名称 学院名称 地区 实名认证 职业认证 手机号码 队长 签领/开户行及银行卡号 审批时间 审批人), :height => 25,:style => blue_cell
|
||||
|
||||
@all_prize_users.each_with_index do |prize_user, index|
|
||||
user = prize_user.user
|
||||
data = [
|
||||
index + 1,
|
||||
prize_user.rank,
|
||||
prize_user.competition_prize.name,
|
||||
prize_user.competition_team_id,
|
||||
prize_user.competition_team.name,
|
||||
user.real_name,
|
||||
user.identity,
|
||||
user.student_id,
|
||||
user.school_name,
|
||||
user.department_name,
|
||||
user.location,
|
||||
user.auth_status,
|
||||
user.pro_status,
|
||||
user.phone,
|
||||
prize_user.leader? ? "是" : "-",
|
||||
[prize_user.extra&.[]('bank'), prize_user.extra&.[]('second_bank'), prize_user.extra&.[]('card_no')].compact.join('/'),
|
||||
prize_user.approved_at&.strftime('%Y-%m-%d %H:%M'),
|
||||
prize_user.approver&.real_name
|
||||
]
|
||||
sheet.add_row(data)
|
||||
end
|
||||
end
|
||||
end
|
@ -0,0 +1,33 @@
|
||||
<table class="table table-hover text-center competition-prize-user-list-table">
|
||||
<thead class="thead-light">
|
||||
<tr>
|
||||
<th width="6%">奖项</th>
|
||||
<th width="5%">排名</th>
|
||||
<th width="10%" class="text-left">战队名称</th>
|
||||
<th width="8%">真实姓名</th>
|
||||
<th width="5%">职业</th>
|
||||
<th width="8%">学号</th>
|
||||
<th width="10%">单位</th>
|
||||
<th width="5%">实名</th>
|
||||
<th width="5%">职业</th>
|
||||
<th width="5%">手机</th>
|
||||
<th width="5%">队长</th>
|
||||
<th width="10%">审批时间</th>
|
||||
<th width="8%">审批人</th>
|
||||
<th width="10%">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody style="overflow-wrap:break-word;">
|
||||
<% if prize_users.present? %>
|
||||
<% prize_users.each do |prize_user| %>
|
||||
<tr class="competition-prize-user-item-<%= prize_user.id %>">
|
||||
<%= render('cooperative/competition_prize_users/shared/tr', prize_user: prize_user) %>
|
||||
</tr>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<%= render 'cooperative/shared/no_data_for_table' %>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<%= render partial: 'cooperative/shared/paginate', locals: { objects: prize_users } %>
|
@ -0,0 +1,35 @@
|
||||
<%- user = prize_user.user -%>
|
||||
<td><%= prize_user.competition_prize.name %></td>
|
||||
<td><%= prize_user.rank %></td>
|
||||
<td class="text-left"><%= prize_user.competition_team.name %></td>
|
||||
<td><%= user.real_name %></td>
|
||||
<td><%= user.identity %></td>
|
||||
<td><%= user.is_teacher? ? user.user_extension.technical_title : user.user_extension.student_id %></td>
|
||||
<td><%= user.school_name %></td>
|
||||
<td><%= display_auth_state(user.authentication?, user.process_real_name_apply.present?) %></td>
|
||||
<td><%= display_auth_state(user.professional_certification?, user.process_professional_apply.present?) %></td>
|
||||
<td><%= display_auth_state user.phone_binded? %></td>
|
||||
<td><%= display_auth_state prize_user.leader?, error: '' %></td>
|
||||
<td><%= display_text prize_user.approved_at&.strftime('%Y-%m-%d %H:%M') %></td>
|
||||
<td><%= display_text prize_user.approver&.real_name %></td>
|
||||
|
||||
<td class="action-container">
|
||||
<% if prize_user.leader? && prize_user.competition_prize.category == 'bonus' %>
|
||||
<% bank_content = [prize_user.extra&.[]('bank'), prize_user.extra&.[]('second_bank'), prize_user.extra&.[]('card_no')].compact.join('<br>').presence || '无' %>
|
||||
<%= javascript_void_link('查看银行账户', data: { toggle: 'tooltip', title: bank_content.html_safe, html: true, placement: 'left', trigger: 'click' }) %>
|
||||
<% prize_module = prize_user.competition&.competition_modules.find_by(module_type: 'certificate') %>
|
||||
<% if prize_module %>
|
||||
<%= link_to('编辑', EduSetting.get("host_name").to_s + "/competitions/#{prize_user.competition&.identifier}?menu=#{prize_module&.id}&user_id=#{user.id}", target: "_blank") %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<% if prize_user.pending? %>
|
||||
<%= link_to('审批通过', approve_cooperative_competition_competition_prize_user_path(prize_user.competition, prize_user),
|
||||
data: { confirm: '确认审批通过吗?' },
|
||||
remote: true, method: :post, class: 'approve-action') %>
|
||||
<% else %>
|
||||
<%= link_to('撤销审批', unapprove_cooperative_competition_competition_prize_user_path(prize_user.competition, prize_user),
|
||||
data: { confirm: '确认撤销审批吗?' },
|
||||
remote: true, method: :post, class: 'approve-action') %>
|
||||
<% end %>
|
||||
</td>
|
@ -0,0 +1 @@
|
||||
$('.competition-prize-user-list-container .competition-prize-user-item-<%= @prize_user.id %>').html("<%= j( render partial: 'cooperative/competition_prize_users/shared/tr', locals: { prize_user: @prize_user } ) %>");
|
@ -0,0 +1,2 @@
|
||||
$('.cooperative-modal-container').html("<%= j( render partial: 'cooperative/competition_prizes/shared/save_competition_prize_modal', locals: { prize: @prize, title: '编辑奖项', form_method: 'PATCH' } ) %>");
|
||||
$('.modal.cooperative-save-competition-prize-modal').modal('show');
|
@ -0,0 +1 @@
|
||||
$('#competition-prize-card .competition-prize-table tbody').html("<%= j( render partial: 'cooperative/competition_settings/shared/competition_prizes', locals: { competition: @competition } ) %>");
|
@ -0,0 +1,2 @@
|
||||
$('.cooperative-modal-container').html("<%= j( render partial: 'cooperative/competition_prizes/shared/save_competition_prize_modal', locals: { prize: @prize, title: '新建奖项', form_method: 'POST' } ) %>");
|
||||
$('.modal.cooperative-save-competition-prize-modal').modal('show');
|
@ -0,0 +1,29 @@
|
||||
<div class="modal fade cooperative-save-competition-prize-modal" tabindex="-1" role="dialog" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title"><%= title ||= '保存奖项设置' %></h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<%= simple_form_for([:cooperative, prize.competition, prize], data: { form_method: form_method }, html: { class: 'cooperative-save-competition-prize-form' }, defaults: { wrapper_html: { class: 'offset-md-1 col-md-10' } }) do |f| %>
|
||||
|
||||
<%= f.input :name, label: '奖项名称:', placeholder: '请输入奖项名称' %>
|
||||
<%= f.input :num, as: :integer, label: '数量:', placeholder: '请输入数量', input_html: { min: 1 } %>
|
||||
|
||||
<%= f.input :category, label: '奖励类型:' do %>
|
||||
<%= f.select :category, [%w(奖金 bonus), %w(无 unset)], {}, class: 'form-control' %>
|
||||
<% end %>
|
||||
|
||||
<div class="error text-danger"></div>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
|
||||
<button type="button" class="btn btn-primary submit-btn">确认</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue