commit
b1069b9afd
@ -0,0 +1,56 @@
|
||||
# See https://help.github.com/articles/ignoring-files for more about ignoring files.
|
||||
#
|
||||
# If you find yourself ignoring temporary files generated by your text editor
|
||||
# or operating system, you probably want to add a global ignore instead:
|
||||
# git config --global core.excludesfile '~/.gitignore_global'
|
||||
|
||||
# Ignore bundler config.
|
||||
/.bundle
|
||||
|
||||
# mac
|
||||
*.DS_Store
|
||||
|
||||
# Ignore all logfiles and tempfiles.
|
||||
/log/*
|
||||
/tmp/*
|
||||
!/log/.keep
|
||||
!/tmp/.keep
|
||||
|
||||
# Ignore uploaded files in development
|
||||
/storage/*
|
||||
|
||||
/node_modules
|
||||
/yarn-error.log
|
||||
|
||||
# /public/assets
|
||||
.byebug_history
|
||||
|
||||
# Ignore master key for decrypting credentials and more.
|
||||
/config/master.key
|
||||
/config/database.yml
|
||||
/.idea/*
|
||||
|
||||
# Ignore react node_modules
|
||||
/public/react/build
|
||||
/public/react/build/
|
||||
/public/react/node_modules/
|
||||
/public/react/config/stats.json
|
||||
/public/react/stats.json
|
||||
|
||||
/public/npm-debug.log
|
||||
|
||||
# avatars
|
||||
/public/images/avatars
|
||||
|
||||
/config/secrets.yml
|
||||
/files/archiveZip/*
|
||||
/files/cache_store/*
|
||||
public/upload.html
|
||||
/config/configuration.yml
|
||||
/config/initializers/gitlab_config.rb
|
||||
/db/schema.rb
|
||||
.vscode/
|
||||
vendor/bundle/
|
||||
.ruby-version
|
||||
.ruby-gemset
|
||||
|
@ -0,0 +1,86 @@
|
||||
source 'https://gems.ruby-china.com'
|
||||
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
|
||||
|
||||
ruby '2.3.7'
|
||||
|
||||
gem 'rails', '~> 5.2.0'
|
||||
gem 'mysql2', '>= 0.4.4', '< 0.6.0'
|
||||
gem 'puma', '~> 3.11'
|
||||
gem 'sass-rails', '~> 5.0'
|
||||
gem 'uglifier', '>= 1.3.0'
|
||||
|
||||
# gem 'coffee-rails', '~> 4.2'
|
||||
# gem 'turbolinks', '~> 5'
|
||||
gem 'jbuilder', '~> 2.5'
|
||||
|
||||
gem 'grape-entity', '~> 0.7.1'
|
||||
gem 'kaminari', '~> 1.1', '>= 1.1.1'
|
||||
|
||||
gem 'bootsnap', '>= 1.1.0', require: false
|
||||
|
||||
gem 'gitlab', path: 'lib/gitlab-cli'
|
||||
|
||||
gem 'rack-cors'
|
||||
gem 'redis-rails'
|
||||
gem 'roo-xls'
|
||||
gem 'simple_xlsx_reader'
|
||||
|
||||
gem 'rubyzip'
|
||||
|
||||
gem 'spreadsheet'
|
||||
gem 'ruby-ole'
|
||||
# 导出为xlsx
|
||||
gem 'axlsx', '~> 3.0.0.pre'
|
||||
gem 'axlsx_rails', '~> 0.5.2'
|
||||
|
||||
gem 'oauth2'
|
||||
#导出为pdf
|
||||
gem 'pdfkit'
|
||||
gem 'wkhtmltopdf-binary'
|
||||
|
||||
#gem 'iconv'
|
||||
|
||||
gem 'rqrcode', '~> 0.10.1'
|
||||
gem 'rqrcode_png'
|
||||
|
||||
gem 'acts-as-taggable-on', '~> 6.0'
|
||||
|
||||
group :development, :test do
|
||||
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
|
||||
gem 'rspec-rails', '~> 3.8'
|
||||
end
|
||||
|
||||
group :development do
|
||||
gem 'awesome_print'
|
||||
gem 'web-console', '>= 3.3.0'
|
||||
gem 'listen', '>= 3.0.5', '< 3.2'
|
||||
gem 'spring'
|
||||
gem 'spring-watcher-listen', '~> 2.0.0'
|
||||
end
|
||||
|
||||
group :test do
|
||||
gem 'capybara', '>= 2.15', '< 4.0'
|
||||
gem 'selenium-webdriver'
|
||||
gem 'chromedriver-helper'
|
||||
end
|
||||
|
||||
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
|
||||
|
||||
#编码检测
|
||||
gem 'rchardet', '~> 1.8'
|
||||
|
||||
# http client
|
||||
gem 'faraday', '~> 0.15.4'
|
||||
|
||||
# view
|
||||
gem 'active_decorator'
|
||||
|
||||
# i18n
|
||||
gem 'rails-i18n', '~> 5.1'
|
||||
|
||||
# job
|
||||
gem 'sidekiq'
|
||||
|
||||
# batch insert
|
||||
gem 'bulk_insert'
|
||||
|
@ -0,0 +1,354 @@
|
||||
PATH
|
||||
remote: lib/gitlab-cli
|
||||
specs:
|
||||
gitlab (3.2.0)
|
||||
httparty
|
||||
terminal-table
|
||||
|
||||
GEM
|
||||
remote: https://gems.ruby-china.com/
|
||||
specs:
|
||||
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.5.2)
|
||||
public_suffix (>= 2.0.2, < 4.0)
|
||||
archive-zip (0.11.0)
|
||||
io-like (~> 0.3.0)
|
||||
arel (9.0.0)
|
||||
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)
|
||||
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)
|
||||
erubi (1.7.1)
|
||||
execjs (2.7.0)
|
||||
faraday (0.15.4)
|
||||
multipart-post (>= 1.2, < 3)
|
||||
ffi (1.9.25)
|
||||
globalid (0.4.1)
|
||||
activesupport (>= 4.2.0)
|
||||
grape-entity (0.7.1)
|
||||
activesupport (>= 4.0)
|
||||
multi_json (>= 1.3.2)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
pdfkit (0.8.4.1)
|
||||
public_suffix (3.0.2)
|
||||
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)
|
||||
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)
|
||||
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_xlsx_reader (1.0.4)
|
||||
nokogiri
|
||||
rubyzip
|
||||
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)
|
||||
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
|
||||
active_decorator
|
||||
acts-as-taggable-on (~> 6.0)
|
||||
awesome_print
|
||||
axlsx (~> 3.0.0.pre)
|
||||
axlsx_rails (~> 0.5.2)
|
||||
bootsnap (>= 1.1.0)
|
||||
bulk_insert
|
||||
byebug
|
||||
capybara (>= 2.15, < 4.0)
|
||||
chromedriver-helper
|
||||
faraday (~> 0.15.4)
|
||||
gitlab!
|
||||
grape-entity (~> 0.7.1)
|
||||
jbuilder (~> 2.5)
|
||||
kaminari (~> 1.1, >= 1.1.1)
|
||||
listen (>= 3.0.5, < 3.2)
|
||||
mysql2 (>= 0.4.4, < 0.6.0)
|
||||
oauth2
|
||||
pdfkit
|
||||
puma (~> 3.11)
|
||||
rack-cors
|
||||
rails (~> 5.2.0)
|
||||
rails-i18n (~> 5.1)
|
||||
rchardet (~> 1.8)
|
||||
redis-rails
|
||||
roo-xls
|
||||
rqrcode (~> 0.10.1)
|
||||
rqrcode_png
|
||||
rspec-rails (~> 3.8)
|
||||
ruby-ole
|
||||
rubyzip
|
||||
sass-rails (~> 5.0)
|
||||
selenium-webdriver
|
||||
sidekiq
|
||||
simple_xlsx_reader
|
||||
spreadsheet
|
||||
spring
|
||||
spring-watcher-listen (~> 2.0.0)
|
||||
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,6 @@
|
||||
# Add your own tasks in files placed in lib/tasks ending in .rake,
|
||||
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
|
||||
|
||||
require_relative 'config/application'
|
||||
|
||||
Rails.application.load_tasks
|
@ -0,0 +1,3 @@
|
||||
//= link_tree ../images
|
||||
//= link_directory ../javascripts .js
|
||||
//= link_directory ../stylesheets .css
|
After Width: | Height: | Size: 110 KiB |
@ -0,0 +1,16 @@
|
||||
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
||||
// listed below.
|
||||
//
|
||||
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, or any plugin's
|
||||
// vendor/assets/javascripts directory can be referenced here using a relative path.
|
||||
//
|
||||
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
||||
// compiled file. JavaScript code in this file should be added after the last require_* statement.
|
||||
//
|
||||
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
|
||||
// about supported directives.
|
||||
//
|
||||
//= require rails-ujs
|
||||
//= require activestorage
|
||||
//= require turbolinks
|
||||
//= require_tree .
|
@ -0,0 +1,3 @@
|
||||
# Place all the behaviors and hooks related to the matching controller here.
|
||||
# All this logic will automatically be available in application.js.
|
||||
# You can use CoffeeScript in this file: http://coffeescript.org/
|
@ -0,0 +1,13 @@
|
||||
// Action Cable provides the framework to deal with WebSockets in Rails.
|
||||
// You can generate new channels where WebSocket features live using the `rails generate channel` command.
|
||||
//
|
||||
//= require action_cable
|
||||
//= require_self
|
||||
//= require_tree ./channels
|
||||
|
||||
(function() {
|
||||
this.App || (this.App = {});
|
||||
|
||||
App.cable = ActionCable.createConsumer();
|
||||
|
||||
}).call(this);
|
@ -0,0 +1,4 @@
|
||||
|
||||
# Place all the behaviors and hooks related to the matching controller here.
|
||||
# All this logic will automatically be available in application.js.
|
||||
# You can use CoffeeScript in this file: http://coffeescript.org/
|
@ -0,0 +1,3 @@
|
||||
# Place all the behaviors and hooks related to the matching controller here.
|
||||
# All this logic will automatically be available in application.js.
|
||||
# You can use CoffeeScript in this file: http://coffeescript.org/
|
@ -0,0 +1,3 @@
|
||||
# Place all the behaviors and hooks related to the matching controller here.
|
||||
# All this logic will automatically be available in application.js.
|
||||
# You can use CoffeeScript in this file: http://coffeescript.org/
|
@ -0,0 +1,3 @@
|
||||
# Place all the behaviors and hooks related to the matching controller here.
|
||||
# All this logic will automatically be available in application.js.
|
||||
# You can use CoffeeScript in this file: http://coffeescript.org/
|
@ -0,0 +1,3 @@
|
||||
# Place all the behaviors and hooks related to the matching controller here.
|
||||
# All this logic will automatically be available in application.js.
|
||||
# You can use CoffeeScript in this file: http://coffeescript.org/
|
@ -0,0 +1,3 @@
|
||||
# Place all the behaviors and hooks related to the matching controller here.
|
||||
# All this logic will automatically be available in application.js.
|
||||
# You can use CoffeeScript in this file: http://coffeescript.org/
|
@ -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,3 @@
|
||||
# Place all the behaviors and hooks related to the matching controller here.
|
||||
# All this logic will automatically be available in application.js.
|
||||
# You can use CoffeeScript in this file: http://coffeescript.org/
|
@ -0,0 +1,3 @@
|
||||
# Place all the behaviors and hooks related to the matching controller here.
|
||||
# All this logic will automatically be available in application.js.
|
||||
# You can use CoffeeScript in this file: http://coffeescript.org/
|
@ -0,0 +1,3 @@
|
||||
# Place all the behaviors and hooks related to the matching controller here.
|
||||
# All this logic will automatically be available in application.js.
|
||||
# You can use CoffeeScript in this file: http://coffeescript.org/
|
@ -0,0 +1,3 @@
|
||||
# Place all the behaviors and hooks related to the matching controller here.
|
||||
# All this logic will automatically be available in application.js.
|
||||
# You can use CoffeeScript in this file: http://coffeescript.org/
|
@ -0,0 +1,3 @@
|
||||
# Place all the behaviors and hooks related to the matching controller here.
|
||||
# All this logic will automatically be available in application.js.
|
||||
# You can use CoffeeScript in this file: http://coffeescript.org/
|
@ -0,0 +1,3 @@
|
||||
# Place all the behaviors and hooks related to the matching controller here.
|
||||
# All this logic will automatically be available in application.js.
|
||||
# You can use CoffeeScript in this file: http://coffeescript.org/
|
@ -0,0 +1,3 @@
|
||||
# Place all the behaviors and hooks related to the matching controller here.
|
||||
# All this logic will automatically be available in application.js.
|
||||
# You can use CoffeeScript in this file: http://coffeescript.org/
|
@ -0,0 +1,3 @@
|
||||
# Place all the behaviors and hooks related to the matching controller here.
|
||||
# All this logic will automatically be available in application.js.
|
||||
# You can use CoffeeScript in this file: http://coffeescript.org/
|
@ -0,0 +1,3 @@
|
||||
# Place all the behaviors and hooks related to the matching controller here.
|
||||
# All this logic will automatically be available in application.js.
|
||||
# You can use CoffeeScript in this file: http://coffeescript.org/
|
@ -0,0 +1,3 @@
|
||||
# Place all the behaviors and hooks related to the matching controller here.
|
||||
# All this logic will automatically be available in application.js.
|
||||
# You can use CoffeeScript in this file: http://coffeescript.org/
|
@ -0,0 +1,3 @@
|
||||
# Place all the behaviors and hooks related to the matching controller here.
|
||||
# All this logic will automatically be available in application.js.
|
||||
# You can use CoffeeScript in this file: http://coffeescript.org/
|
@ -0,0 +1,3 @@
|
||||
# Place all the behaviors and hooks related to the matching controller here.
|
||||
# All this logic will automatically be available in application.js.
|
||||
# You can use CoffeeScript in this file: http://coffeescript.org/
|
@ -0,0 +1,3 @@
|
||||
# Place all the behaviors and hooks related to the matching controller here.
|
||||
# All this logic will automatically be available in application.js.
|
||||
# You can use CoffeeScript in this file: http://coffeescript.org/
|
@ -0,0 +1,3 @@
|
||||
# Place all the behaviors and hooks related to the matching controller here.
|
||||
# All this logic will automatically be available in application.js.
|
||||
# You can use CoffeeScript in this file: http://coffeescript.org/
|
@ -0,0 +1,3 @@
|
||||
# Place all the behaviors and hooks related to the matching controller here.
|
||||
# All this logic will automatically be available in application.js.
|
||||
# You can use CoffeeScript in this file: http://coffeescript.org/
|
@ -0,0 +1,3 @@
|
||||
# Place all the behaviors and hooks related to the matching controller here.
|
||||
# All this logic will automatically be available in application.js.
|
||||
# You can use CoffeeScript in this file: http://coffeescript.org/
|
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
||||
* listed below.
|
||||
*
|
||||
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, or any plugin's
|
||||
* vendor/assets/stylesheets directory can be referenced here using a relative path.
|
||||
*
|
||||
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
||||
* compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
|
||||
* files in this directory. Styles in this file should be added after the last require_* statement.
|
||||
* It is generally better to create a new file per style scope.
|
||||
*
|
||||
*= require_tree .
|
||||
*= require_self
|
||||
|
||||
*/
|
@ -0,0 +1,3 @@
|
||||
// Place all the styles related to the boards 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 Challenges 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 course_groups 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 course_modules 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 course_second_categories 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 courses 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 Discusses 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 edu_settings 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 games 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 graduation_tasks 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 graduation_topics 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 graduation_works 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 Home 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 homework_commons 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 memos 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 myshixuns 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 QuestionBank 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 repositories controller here.
|
||||
// They will automatically be included in application.css.
|
||||
// You can use Sass (SCSS) here: http://sass-lang.com/
|
@ -0,0 +1,84 @@
|
||||
body {
|
||||
background-color: #fff;
|
||||
color: #333;
|
||||
margin: 33px;
|
||||
font-family: verdana, arial, helvetica, sans-serif;
|
||||
font-size: 13px;
|
||||
line-height: 18px;
|
||||
}
|
||||
|
||||
p, ol, ul, td {
|
||||
font-family: verdana, arial, helvetica, sans-serif;
|
||||
font-size: 13px;
|
||||
line-height: 18px;
|
||||
}
|
||||
|
||||
pre {
|
||||
background-color: #eee;
|
||||
padding: 10px;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #000;
|
||||
|
||||
&:visited {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: #fff;
|
||||
background-color: #000;
|
||||
}
|
||||
}
|
||||
|
||||
th {
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 0 5px 7px;
|
||||
}
|
||||
|
||||
div {
|
||||
&.field, &.actions {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
#notice {
|
||||
color: green;
|
||||
}
|
||||
|
||||
.field_with_errors {
|
||||
padding: 2px;
|
||||
background-color: red;
|
||||
display: table;
|
||||
}
|
||||
|
||||
#error_explanation {
|
||||
width: 450px;
|
||||
border: 2px solid red;
|
||||
padding: 7px 7px 0;
|
||||
margin-bottom: 20px;
|
||||
background-color: #f0f0f0;
|
||||
|
||||
h2 {
|
||||
text-align: left;
|
||||
font-weight: bold;
|
||||
padding: 5px 5px 5px 15px;
|
||||
font-size: 12px;
|
||||
margin: -7px -7px 0;
|
||||
background-color: #c00;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
ul li {
|
||||
font-size: 12px;
|
||||
list-style: square;
|
||||
}
|
||||
}
|
||||
|
||||
label {
|
||||
display: block;
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
// Place all the styles related to the schools 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 stages 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 StudentWorks 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 Subjects 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 tem_tests 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 Users controller here.
|
||||
// They will automatically be included in application.css.
|
||||
// You can use Sass (SCSS) here: http://sass-lang.com/
|
@ -0,0 +1,4 @@
|
||||
module ApplicationCable
|
||||
class Channel < ActionCable::Channel::Base
|
||||
end
|
||||
end
|
@ -0,0 +1,4 @@
|
||||
module ApplicationCable
|
||||
class Connection < ActionCable::Connection::Base
|
||||
end
|
||||
end
|
@ -0,0 +1,11 @@
|
||||
class ReactConstraint
|
||||
|
||||
|
||||
def matches?(request)
|
||||
# stuff
|
||||
#
|
||||
!File.exists?(File.join(Rails.root, "public", request.fullpath.split('?').first))
|
||||
end
|
||||
|
||||
|
||||
end
|
@ -0,0 +1,86 @@
|
||||
class BoardsController < ApplicationController
|
||||
before_action :require_login
|
||||
before_action :find_course, only: [:create]
|
||||
before_action :set_board, except: [:create]
|
||||
before_action :teacher_allowed
|
||||
|
||||
def index
|
||||
@boards = @course.boards.includes(messages: [:last_reply, :author]);
|
||||
end
|
||||
|
||||
def show
|
||||
|
||||
end
|
||||
|
||||
def new
|
||||
end
|
||||
|
||||
def create
|
||||
ActiveRecord::Base.transaction do
|
||||
begin
|
||||
board = @course.course_board
|
||||
new_board = Board.new(board_params)
|
||||
new_board.course_id = @course.id
|
||||
new_board.project_id = -1
|
||||
new_board.parent_id = board.try(:id)
|
||||
new_board.position = board.children.count + 1
|
||||
new_board.save!
|
||||
normal_status(0, "添加成功")
|
||||
rescue Exception => e
|
||||
uid_logger_error(e.message)
|
||||
tip_exception(e.message)
|
||||
raise ActiveRecord::Rollback
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# 子目录的拖动
|
||||
def move_category
|
||||
tip_exception("移动失败") if params[:position].blank?
|
||||
unless params[:position].to_i == @board.position
|
||||
course_board = @course.course_board
|
||||
if params[:position].to_i < @board.position
|
||||
course_board.children.where("position < #{@board.position} and position >= ?", params[:position]).update_all("position = position + 1")
|
||||
else
|
||||
course_board.children.where("position > #{@board.position} and position <= ?", params[:position]).update_all("position = position - 1")
|
||||
end
|
||||
@board.update_attributes(position: params[:position])
|
||||
normal_status(0, "移动成功")
|
||||
else
|
||||
normal_status(-1, "位置没有变化")
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
ActiveRecord::Base.transaction do
|
||||
begin
|
||||
@course_board = @course.course_board
|
||||
@course_board.children.where("position > #{@board.position}").update_all("position = position - 1")
|
||||
@board.messages.update_all(board_id: @course_board.id)
|
||||
@board.destroy
|
||||
rescue Exception => e
|
||||
uid_logger_error(e.message)
|
||||
tip_exception("子目录删除失败")
|
||||
raise ActiveRecord::Rollback
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
@board.update_attributes(board_params)
|
||||
normal_status(0, "更新成功")
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_board
|
||||
@board = Board.find_by!(id: params[:id])
|
||||
@course = @board.course
|
||||
end
|
||||
|
||||
def board_params
|
||||
tip_exception("子目录名称不能为空") if params[:name].blank?
|
||||
tip_exception("已存在同名讨论区") if @course.boards.exists?(name: params[:name].strip)
|
||||
params.require(:board).permit(:name)
|
||||
end
|
||||
end
|
@ -0,0 +1,305 @@
|
||||
class ChallengesController < ApplicationController
|
||||
before_action :require_login
|
||||
before_action :find_shixun, only: [:new, :create, :index]
|
||||
skip_before_action :verify_authenticity_token, only: [:create, :update, :create_choose_question, :crud_answer]
|
||||
before_action :find_challenge, only: [:edit, :show, :update, :create_choose_question, :index_down, :index_up,
|
||||
:edit_choose_question, :show_choose_question, :destroy_challenge_choose,
|
||||
:update_choose_question, :destroy, :crud_answer, :answer]
|
||||
# before_action :allowed, except: [:index, :show, :edit_choose_question, :edit]
|
||||
|
||||
|
||||
include ShixunsHelper
|
||||
include ChallengesHelper
|
||||
|
||||
# 新建实践题
|
||||
def new
|
||||
@position = @shixun.challenges.count + 1
|
||||
@st = params[:st].to_i
|
||||
@task_pass_default = PlatformSample.find_by(samples_type: "taskPass").try(:contents)
|
||||
end
|
||||
|
||||
# params
|
||||
# challenge:{"subject": "标题", "task_pass": "过关任务",
|
||||
# "diffculty": "关卡难度", "score": "关卡分数", "st": "关卡类型"} 关卡相关信息
|
||||
# challenge_tag: 关卡标签
|
||||
#
|
||||
def create
|
||||
ActiveRecord::Base.transaction do
|
||||
begin
|
||||
@challenge = Challenge.new(challenge_params)
|
||||
@challenge.position = @shixun.challenges.count + 1
|
||||
@challenge.shixun_id = @shixun.id
|
||||
@challenge.user_id = current_user.id
|
||||
@challenge.modify_time = Time.now
|
||||
@challenge.save!
|
||||
|
||||
# 实训是否需要重置, 非实践任务创建第一个阶段调用, 避免不包含实践任务的实训进行模拟实战报错 todo: 新建实训需要重置TPI
|
||||
# shixun_modify_status_without_publish(@shixun, 1) if @challenge.position != 1
|
||||
|
||||
tags = params[:challenge_tag]
|
||||
if tags.present?
|
||||
tags.each do |tag|
|
||||
# TODO 创建tag的时候为什么一直报challenge choose必须存在??
|
||||
ChallengeTag.create!(name: tag, challenge_id: @challenge.id)
|
||||
end
|
||||
end
|
||||
rescue Exception => e
|
||||
uid_logger_error("create challenge failed #{e}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# 创建选择题
|
||||
def create_choose_question
|
||||
ActiveRecord::Base.transaction do
|
||||
begin
|
||||
@challenge_choose = ChallengeChoose.new(chooce_params)
|
||||
@challenge_choose.position = @challenge.challenge_chooses.count + 1
|
||||
@challenge_choose.category = @challenge_choose.standard_answer.length == 1 ? 1 : 2
|
||||
@challenge_choose.challenge_id = @challenge.id
|
||||
|
||||
if @challenge_choose.save!
|
||||
# 创建选项
|
||||
params[:question][:cnt].each_with_index do |test, index|
|
||||
answer = params[:choice][:answer][index]
|
||||
ChallengeQuestion.create(:option_name => test,
|
||||
:challenge_choose_id => @challenge_choose.id,
|
||||
:position => index, :right_key => answer)
|
||||
end
|
||||
# 创建单选多选的技能标签
|
||||
if params[:challenge_tag].present?
|
||||
params[:challenge_tag].each do |tag|
|
||||
ChallengeTag.create(:name => tag, :challenge_choose_id => @challenge_choose.id, :challenge_id => @challenge.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
rescue Exception => e
|
||||
raise ActiveRecord::Rollback
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# 选择题详情页面
|
||||
def show_choose_question
|
||||
@challenge_choose = ChallengeChoose.find params[:choose_id]
|
||||
|
||||
end
|
||||
|
||||
# 选择题更新页面
|
||||
def update_choose_question
|
||||
@challenge_choose = ChallengeChoose.find(params[:choose_id])
|
||||
ActiveRecord::Base.transaction do
|
||||
if params[:standard_answer] != @challenge_choose.standard_answer
|
||||
@challenge.update_column(:modify_time, Time.now)
|
||||
end
|
||||
@challenge_choose.update_attributes(chooce_params)
|
||||
# 单选多选题的更新
|
||||
category = @challenge_choose.standard_answer.length > 1 ? 2 : 1
|
||||
@challenge_choose.update_column(:category, category)
|
||||
begin
|
||||
@challenge_choose.challenge_questions.delete_all
|
||||
params[:question][:cnt].each_with_index do |test, index|
|
||||
answer = params[:choice][:answer][index]
|
||||
ChallengeQuestion.create(:option_name => test, :challenge_choose_id => @challenge_choose.id, :position => index, :right_key => answer)
|
||||
end
|
||||
@challenge_choose.challenge_tags.delete_all unless @challenge_choose.challenge_tags.blank?
|
||||
if params[:challenge_tag].present?
|
||||
params[:challenge_tag].each do |tag|
|
||||
ChallengeTag.create(:name => tag, :challenge_choose_id => @challenge_choose.id, :challenge_id => @challenge.id)
|
||||
end
|
||||
end
|
||||
@challenge_choose = ChallengeChoose.find params[:choose_id]
|
||||
rescue Exception => e
|
||||
raise ActiveRecord::Rollback
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# 选择题的编辑
|
||||
def edit_choose_question
|
||||
@challenge_choose = ChallengeChoose.find params[:choose_id]
|
||||
end
|
||||
|
||||
def destroy_challenge_choose
|
||||
ActiveRecord::Base.transaction do
|
||||
@challenge_choose = ChallengeChoose.where(:id => params[:choose_id]).first
|
||||
pos = @challenge_choose.position
|
||||
@challenge.challenge_chooses.where("position > ?", pos).update_all("position = position - 1")
|
||||
@challenge_choose.destroy
|
||||
@status = 1
|
||||
# 发起重置请求 TODO: 重置实训需要后续做
|
||||
# shixun_modify_status_without_publish(@shixun, 1)
|
||||
end
|
||||
end
|
||||
|
||||
# 编辑模式
|
||||
# tab 0,nil 过关任务, 1 评测设置, 2 参考答案
|
||||
def edit
|
||||
@tab = params[:tab].to_i
|
||||
@power = current_user.manager_of_shixun?(@shixun) && @shixun.status == 0
|
||||
challenge_num = Challenge.where(:shixun_id => @shixun).count
|
||||
@position = @challenge.position
|
||||
@chooses = @challenge.challenge_chooses
|
||||
if @position < challenge_num
|
||||
@next_challenge = Challenge.where(:shixun_id => @shixun, :position => @position + 1).first
|
||||
end
|
||||
@prev_challenge = Challenge.where(:shixun_id => @shixun, :position => @position - 1).first if @position - 1 > 0
|
||||
end
|
||||
|
||||
def index
|
||||
uid_logger("identifier: #{params}")
|
||||
# 通过调试发现 这里includes(:games)性能会慢10倍
|
||||
@challenges = @shixun.challenges.fields_for_list
|
||||
@editable = current_user.manager_of_shixun?(@shixun) && @shixun.status == 0
|
||||
@user = current_user
|
||||
end
|
||||
|
||||
def show
|
||||
@tab = params[:tab].nil? ? 1 : params[:tab].to_i
|
||||
challenge_num = Challenge.where(shixun_id: @shixun).count
|
||||
@power = current_user.manager_of_shixun?(@shixun) && @shixun.status == 0
|
||||
@position = @challenge.position
|
||||
if @position < challenge_num
|
||||
@next_challenge = Challenge.where(:shixun_id => @shixun, :position => @position + 1).first
|
||||
end
|
||||
@prev_challenge = Challenge.where(:shixun_id => @shixun, :position => @position - 1).first if @position - 1 > 0
|
||||
end
|
||||
|
||||
# tab 0:过关任务的更新; 1:评测设置的更新; 2:表示参考答案的更新;
|
||||
def update
|
||||
ActiveRecord::Base.transaction do
|
||||
tab = params[:tab].to_i
|
||||
@challenge.update_attributes(challenge_params)
|
||||
if tab == 0 && @challenge.st == 0
|
||||
@challenge.challenge_tags.delete_all
|
||||
if params[:challenge_tag].present?
|
||||
params[:challenge_tag].each do |input|
|
||||
ChallengeTag.create!(:name => input, :challenge_id => @challenge.id)
|
||||
end
|
||||
end
|
||||
elsif tab == 1
|
||||
path = @challenge.path
|
||||
exec_path = @challenge.exec_path
|
||||
test_set = @challenge.test_sets
|
||||
sets_output = test_set.map(&:output)
|
||||
sets_input = test_set.map(&:input)
|
||||
sets_open = test_set.map(&:is_public)
|
||||
set_score = test_set.map(&:score)
|
||||
params_hidden = params[:test_set].map{|set| set[:hidden].to_i == 0}
|
||||
params_output = params[:test_set].map{|set| set[:output] }
|
||||
params_input = params[:test_set].map{|set| set[:input] }
|
||||
params_score = params[:test_set].map{|set| set[:score]}
|
||||
# 测试集变化则需要更新(输入、 输出、 是否隐藏)
|
||||
if sets_output != params_output || sets_open != params_hidden || sets_input != params_input || set_score != params_score
|
||||
test_set.delete_all unless test_set.blank?
|
||||
params[:test_set].each_with_index do |set, index|
|
||||
TestSet.create(:challenge_id => @challenge.id,
|
||||
:input => "#{set[:input]}",
|
||||
:output => "#{set[:output]}",
|
||||
:is_public => params_hidden[index],
|
||||
:score => set[:score],
|
||||
:position => (index + 1))
|
||||
end
|
||||
@challenge.update_column(:modify_time, Time.now)
|
||||
# 测试集的
|
||||
@shixun.myshixuns.update_all(:system_tip => 0)
|
||||
end
|
||||
# 关卡评测执行文件如果被修改,需要修改脚本内容
|
||||
script = modify_shixun_script @shixun, @shixun.evaluate_script
|
||||
@shixun.update_column(:evaluate_script, script)
|
||||
# TODO:
|
||||
# if path != params[:challenge][:path]
|
||||
# shixun_modify_status_without_publish(@shixun, 1)
|
||||
# end
|
||||
#Attachment.attach_files(@challenge, params[:attachments])
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
# 参考答案的'增,删,改'
|
||||
# POST: /shixuns/:id/challenges/:id/crud_answer
|
||||
# {'challenge_answer': [
|
||||
# {'name': 'name', contents: 'contents', score: 10},
|
||||
# {...},
|
||||
# {...}, ...]
|
||||
#}
|
||||
def crud_answer
|
||||
raise '参考答案不能为空' if params[:challenge_answer].empty?
|
||||
raise '占比之和必须为100%' if params[:challenge_answer].map{|a| a[:score]}.sum != 100
|
||||
@challenge.challenge_answers.destroy_all if @challenge.challenge_answers
|
||||
params[:challenge_answer].each_with_index do |answer, index|
|
||||
ChallengeAnswer.create(name: answer[:name], contents: answer[:contents],
|
||||
level: index+1, score: answer[:score], challenge_id: @challenge.id)
|
||||
end
|
||||
end
|
||||
|
||||
# 查看参考答案接口
|
||||
def answer
|
||||
@answers = @challenge.challenge_answers
|
||||
end
|
||||
|
||||
def index_down
|
||||
next_challenge = @challenge.next_challenge
|
||||
position = @challenge.position
|
||||
@challenge.update_attribute(:position, (position + 1))
|
||||
next_challenge.update_attribute(:position, next_challenge.position - 1)
|
||||
# 关卡位置被修改,需要修改脚本
|
||||
script = modify_shixun_script @shixun, @shixun.evaluate_script
|
||||
@shixun.update_column(:evaluate_script, script)
|
||||
|
||||
end
|
||||
|
||||
def index_up
|
||||
position = @challenge.position
|
||||
last_challenge = @challenge.last_challenge
|
||||
@challenge.update_attribute(:position, (position - 1))
|
||||
last_challenge.update_attribute(:position, last_challenge.position + 1)
|
||||
# 关卡位置被修改,需要修改脚本
|
||||
script = modify_shixun_script @shixun, @shixun.evaluate_script
|
||||
@shixun.update_column(:evaluate_script, script)
|
||||
end
|
||||
|
||||
def destroy
|
||||
next_challenges = @shixun.challenges.where("position > #{@challenge.position}")
|
||||
next_challenges.update_all("position = position - 1")
|
||||
# Todo: 实训修改后,关卡需要重置
|
||||
# shixun_modify_status_without_publish(@shixun, 1)
|
||||
@challenge.destroy
|
||||
# 关卡位置被删除,需要修改脚本
|
||||
script = modify_shixun_script @shixun, @shixun.evaluate_script
|
||||
@shixun.update_column(:evaluate_script, script)
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
|
||||
def find_shixun
|
||||
@shixun = Shixun.find_by_identifier(params[:shixun_identifier])
|
||||
end
|
||||
|
||||
# 通用接口
|
||||
def find_challenge
|
||||
@challenge = Challenge.find params[:id]
|
||||
@shixun = Shixun.find_by!(identifier: params[:shixun_identifier])
|
||||
end
|
||||
|
||||
def challenge_params
|
||||
params.require(:challenge).permit(:subject, :task_pass, :difficulty, :score, :st, :modify_time, :test_set_average,
|
||||
:path, :exec_path, :show_type, :original_picture_path, :test_set_score,
|
||||
:expect_picture_path, :picture_path, :web_route, :answer)
|
||||
end
|
||||
|
||||
def chooce_params
|
||||
params.require(:challenge_choose).permit(:subject, :answer,
|
||||
:standard_answer, :score, :difficult)
|
||||
end
|
||||
|
||||
def allowed
|
||||
# 实训为发布前,除实训的管理者外,其他人都不人都不允许访问
|
||||
if !current_user.manager_of_shixun?(@shixun) && (@shixun.status < 1 || @shixun.hidden == 1)
|
||||
raise Educoder::TipException.new(403, "..")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
@ -0,0 +1,58 @@
|
||||
class CommonsController < ApplicationController
|
||||
OBJECT_TYPE = %W[message journals_for_message]
|
||||
|
||||
before_action :require_login
|
||||
before_action :validate_object_type
|
||||
before_action :find_object
|
||||
before_action :validate_power
|
||||
|
||||
def delete
|
||||
begin
|
||||
@object.destroy!
|
||||
rescue Exception => e
|
||||
uid_logger_error(e.message)
|
||||
tip_exception(e.message)
|
||||
raise ActiveRecord::Rollback
|
||||
end
|
||||
end
|
||||
|
||||
def hidden
|
||||
action(true)
|
||||
end
|
||||
|
||||
def unhidden
|
||||
action(false)
|
||||
end
|
||||
|
||||
private
|
||||
def find_object
|
||||
begin
|
||||
@object = params[:object_type].strip.classify.constantize.find params[:object_id]
|
||||
rescue Exception => e
|
||||
uid_logger_error(e.message)
|
||||
tip_exception(e.message)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
def validate_object_type
|
||||
return normal_status(2, "缺少object_id参数") if params[:object_id].blank?
|
||||
return normal_status(2, "缺少object_type参数") if params[:object_type].blank?
|
||||
return normal_status(2, "object_type参数格式错误") unless OBJECT_TYPE.include? params[:object_type].strip
|
||||
end
|
||||
|
||||
def validate_power
|
||||
tip_exception(403, "无操作权限") unless current_user.admin?
|
||||
end
|
||||
|
||||
def action(flag)
|
||||
begin
|
||||
@object.has_attribute?(:is_hidden) ? @object.update_attributes(:is_hidden => flag )
|
||||
: @object.update_attributes(:hidden => flag )
|
||||
rescue Exception => e
|
||||
uid_logger_error(e.message)
|
||||
tip_exception(e.message)
|
||||
raise ActiveRecord::Rollback
|
||||
end
|
||||
end
|
||||
end
|
@ -0,0 +1,16 @@
|
||||
module ControllerRescueHandler
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
# rescue_from ActionView::MissingTemplate, with: :object_not_found
|
||||
# rescue_from ActiveRecord::RecordNotFound, with: :object_not_found
|
||||
rescue_from Educoder::TipException, with: :tip_show
|
||||
rescue_from ::ActionView::MissingTemplate, with: :missing_template
|
||||
rescue_from ActiveRecord::RecordNotFound, with: :object_not_found
|
||||
rescue_from ActionController::ParameterMissing, with: :render_parameter_missing
|
||||
# form validation error
|
||||
rescue_from ActiveModel::ValidationError do |ex|
|
||||
render_error(ex.model.errors.full_messages.join(','))
|
||||
end
|
||||
end
|
||||
end
|
@ -0,0 +1,10 @@
|
||||
module ErrorCommon
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
rescue_from Exception do |e|
|
||||
logger.error e
|
||||
render json: {status: -1, message: e.message}
|
||||
end
|
||||
end
|
||||
end
|
@ -0,0 +1,48 @@
|
||||
module GitCommon
|
||||
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
|
||||
end
|
||||
|
||||
|
||||
# ------------------------
|
||||
# 版本库目录结构
|
||||
def repository
|
||||
logger.info("ssssssseeeeeeee#{params}")
|
||||
begin
|
||||
@repo_url = repo_url @repo_path
|
||||
@trees = GitService.file_tree(repo_path: @repo_path, path: @path)
|
||||
logger.info("#11@@#@#@#@111#@@@@###{@trees}")
|
||||
|
||||
# TPI(学员实训)不需要获取最近的一次提交
|
||||
if params[:controller] != "myshixuns" && @trees
|
||||
logger.info("#@@#@#@#@#@@@@###{@trees.try(:count)}")
|
||||
@latest_commit = [GitService.commits(repo_path: @repo_path).first]
|
||||
Rails.logger.info("########## #{@latest_commit}")
|
||||
end
|
||||
rescue Exception => e
|
||||
logger.error(e.message)
|
||||
end
|
||||
end
|
||||
|
||||
def file_content
|
||||
logger.info("#################{@repo_path}, #{@path}")
|
||||
@content = git_fle_content @repo_path, @path
|
||||
end
|
||||
|
||||
# 版本库提交记录
|
||||
# Redo: commit接口需要按倒叙排列
|
||||
def commits
|
||||
begin
|
||||
@commits = GitService.commits(repo_path: @repo_path)
|
||||
logger.info("git first commit is #{@commits.try(:first)}")
|
||||
raise Educoder::TipException.new("请先创建版本库") if @commits.nil?
|
||||
rescue Exception => e
|
||||
uid_logger_error(e.message)
|
||||
raise Educoder::TipException.new("提交记录异常")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
@ -0,0 +1,20 @@
|
||||
module RenderExpand
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
ActionController.add_renderer :pdf do |template, options|
|
||||
file = File.open(Rails.root.join('app/templates', template << '.html.erb'))
|
||||
html = ERB.new(file.read).result(binding)
|
||||
kit = PDFKit.new(html)
|
||||
|
||||
base_css = %w(app/templates/shared/main.css)
|
||||
base_css.each { |css| kit.stylesheets << Rails.root.join(css) }
|
||||
|
||||
Array.wrap(options.delete(:stylesheets)).each do |path|
|
||||
kit.stylesheets << Rails.root.join('app/templates', path)
|
||||
end
|
||||
|
||||
send_data kit.to_pdf, filename: options[:filename], type: 'application/pdf'
|
||||
end
|
||||
end
|
||||
end
|
@ -0,0 +1,19 @@
|
||||
module RenderHelper
|
||||
def render_ok(data = {})
|
||||
render json: { status: 0, message: 'success' }.merge(data)
|
||||
end
|
||||
|
||||
def render_error(message = '')
|
||||
render json: { status: -1, message: message }
|
||||
end
|
||||
|
||||
def render_not_found(message = I18n.t('error.record_not_found'))
|
||||
render json: { status: 404, message: message }
|
||||
# render status: 404, json: { errors: errors }
|
||||
end
|
||||
|
||||
def render_forbidden(message = I18n.t('error.forbidden'))
|
||||
render json: { status: 403, message: message }
|
||||
# render status: 403, json: { errors: errors }
|
||||
end
|
||||
end
|
@ -0,0 +1,64 @@
|
||||
class CourseGroupsController < ApplicationController
|
||||
before_action :require_login
|
||||
before_action :set_group, except: [:create]
|
||||
before_action :find_course, only: [:create]
|
||||
before_action :teacher_allowed
|
||||
|
||||
def create
|
||||
tip_exception("分班名称不能为空") if params[:name].blank?
|
||||
if @course.course_groups.where(name: params[:name]).count > 0
|
||||
normal_status(-1, "已存在同名分班")
|
||||
else
|
||||
@course.course_groups.create!(name: params[:name], position: @course.course_groups.count + 1)
|
||||
normal_status(0, "创建成功")
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
ActiveRecord::Base.transaction do
|
||||
begin
|
||||
@course.course_groups.where("position > #{@group.position}").update_all("position = position - 1")
|
||||
# 将该分班的学生转到未分班
|
||||
@group.course_members.update_all(course_group_id: 0)
|
||||
@group.destroy
|
||||
rescue Exception => e
|
||||
uid_logger_error(e.message)
|
||||
tip_exception("删除分班失败")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# 分班重命名
|
||||
def rename_group
|
||||
tip_exception("名称不能为空") if params[:name].blank?
|
||||
if @course.course_groups.where(name: params[:name]).count > 0
|
||||
normal_status(-1, "已存在同名分班")
|
||||
else
|
||||
@group.update_attributes(name: params[:name].strip)
|
||||
normal_status(0, "更新成功")
|
||||
end
|
||||
end
|
||||
|
||||
# 分班的拖动
|
||||
def move_category
|
||||
tip_exception("移动失败") if params[:position].blank?
|
||||
unless params[:position].to_i == @group.position
|
||||
if params[:position].to_i < @group.position
|
||||
@course.course_groups.where("position < #{@group.position} and position >= ?", params[:position]).update_all("position = position + 1")
|
||||
else
|
||||
@course.course_groups.where("position > #{@group.position} and position <= ?", params[:position]).update_all("position = position - 1")
|
||||
end
|
||||
@group.update_attributes(position: params[:position])
|
||||
normal_status(0, "移动成功")
|
||||
else
|
||||
normal_status(-1, "位置没有变化")
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_group
|
||||
@group = CourseGroup.find_by!(id: params[:id])
|
||||
@course = @group.course
|
||||
end
|
||||
end
|
@ -0,0 +1,60 @@
|
||||
class CourseSecondCategoriesController < ApplicationController
|
||||
before_action :require_login
|
||||
before_action :set_category
|
||||
before_action :teacher_allowed
|
||||
|
||||
# 目录重命名
|
||||
def rename_category
|
||||
tip_exception("毕设子目录不能重命名") if @category.category_type == "graduation"
|
||||
tip_exception("名称不能为空") if params[:name].blank?
|
||||
tip_exception("已存在同名子目录") if @course_module.course_second_categories.exists?(name: params[:name].strip)
|
||||
@category.update_attributes(name: params[:name].strip)
|
||||
normal_status(0, "更新成功")
|
||||
end
|
||||
|
||||
# 子目录的拖动
|
||||
def move_category
|
||||
tip_exception("移动失败") if params[:position].blank?
|
||||
unless params[:position].to_i == @category.position
|
||||
if params[:position].to_i < @category.position
|
||||
@course_module.course_second_categories.where("position < #{@category.position} and position >= ?", params[:position]).update_all("position = position + 1")
|
||||
else
|
||||
@course_module.course_second_categories.where("position > #{@category.position} and position <= ?", params[:position]).update_all("position = position - 1")
|
||||
end
|
||||
@category.update_attributes(position: params[:position])
|
||||
normal_status(0, "移动成功")
|
||||
else
|
||||
normal_status(-1, "位置没有变化")
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
tip_exception("毕设子目录不能删除") if @category.category_type == "graduation"
|
||||
ActiveRecord::Base.transaction do
|
||||
begin
|
||||
@course_module.course_second_categories.where("position > #{@category.position}").update_all("position = position - 1")
|
||||
# 更新相应对象的子目录id
|
||||
if @course_module.module_type == "shixun_homework"
|
||||
@category.homework_commons.update_all(course_second_category_id: 0)
|
||||
@right_url = "/courses/#{@course.id}/shixun_homeworks/#{@course_module.id}"
|
||||
elsif @course_module.module_type == "attachment"
|
||||
Attachment.where(course_second_category_id: @category.id).update_all(course_second_category_id: 0)
|
||||
@right_url = "/courses/#{@course.id}/files/#{@course_module.id}"
|
||||
end
|
||||
|
||||
@category.destroy
|
||||
rescue Exception => e
|
||||
uid_logger_error(e.message)
|
||||
tip_exception("删除子目录失败")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_category
|
||||
@category = CourseSecondCategory.find_by!(id: params[:id])
|
||||
@course_module = @category.course_module
|
||||
@course = @course_module.try(:course)
|
||||
end
|
||||
end
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,20 @@
|
||||
class Ecs::CourseAchievementMethodsController < Ecs::CourseBaseController
|
||||
def show
|
||||
include_associations = { ec_course_achievement_methods: [:ec_course_evaluation, :ec_course_evaluation_subitems] }
|
||||
@course_targets = current_course.ec_course_targets.includes(include_associations)
|
||||
end
|
||||
|
||||
def create
|
||||
@course_target = Ecs::CreateCourseAchievementMethodsService.call(current_course_target, create_params)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def create_params
|
||||
params.permit(course_achievement_methods: %i[id course_evaluation_id course_evaluation_subitem_ids score percentage])
|
||||
end
|
||||
|
||||
def current_course_target
|
||||
@_current_course_target ||= current_course.ec_course_targets.find(params[:course_target_id])
|
||||
end
|
||||
end
|
@ -0,0 +1,9 @@
|
||||
class Ecs::CourseBaseController < Ecs::BaseController
|
||||
def current_course
|
||||
@_current_course ||= EcCourse.find(params[:ec_course_id])
|
||||
end
|
||||
|
||||
def current_year
|
||||
@_current_year ||= current_course.ec_year
|
||||
end
|
||||
end
|
@ -0,0 +1,64 @@
|
||||
class Ecs::CourseEvaluationsController < Ecs::CourseBaseController
|
||||
def index
|
||||
@course_evaluations = current_course.ec_course_evaluations.includes(:ec_course_evaluation_subitems)
|
||||
end
|
||||
|
||||
def create
|
||||
course_evaluation = current_course.ec_course_evaluations.new
|
||||
@course_evaluation = Ecs::SaveCourseEvaluationService.call(course_evaluation, create_params)
|
||||
render 'show'
|
||||
end
|
||||
|
||||
def update
|
||||
@course_evaluation = Ecs::SaveCourseEvaluationService.call(current_course_evaluation, update_params)
|
||||
render 'show'
|
||||
end
|
||||
|
||||
def destroy
|
||||
current_course_evaluation.destroy!
|
||||
render_ok
|
||||
end
|
||||
|
||||
def slimmer
|
||||
course_evaluations = current_course.ec_course_evaluations
|
||||
|
||||
if params[:course_evaluation_id].present?
|
||||
course_evaluations = course_evaluations.where(id: params[:course_evaluation_id])
|
||||
end
|
||||
|
||||
@course_evaluations = course_evaluations.includes(:ec_course_evaluation_subitems)
|
||||
end
|
||||
|
||||
def average_score_import_template
|
||||
@course_evaluation = current_course_evaluation
|
||||
filename = "#{@course_evaluation.name}平均成绩导入模板_#{Time.current.strftime('%Y%m%d%H%M%S')}.xlsx"
|
||||
render xlsx: 'average_score_import_template', filename: filename
|
||||
end
|
||||
|
||||
def detail_score_import_template
|
||||
@course_evaluation = current_course_evaluation
|
||||
filename = "#{@course_evaluation.name}明细成绩导入模板_#{Time.current.strftime('%Y%m%d%H%M%S')}.xlsx"
|
||||
render xlsx: 'detail_score_import_template', filename: filename
|
||||
end
|
||||
|
||||
def import_student_achievement
|
||||
Ecs::ImportCourseStudentAchievementService.call(current_course_evaluation, params[:attachment_id])
|
||||
render_ok
|
||||
rescue Ecs::ImportCourseStudentAchievementService => ex
|
||||
render_error(ex.message)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def create_params
|
||||
params.permit(:name, :evaluation_count, :status, course_evaluation_subitems: [:name])
|
||||
end
|
||||
|
||||
def update_params
|
||||
params.permit(:name, :evaluation_count, :status, course_evaluation_subitems: [:id, :name])
|
||||
end
|
||||
|
||||
def current_course_evaluation
|
||||
@_current_course_evaluation ||= current_course.ec_course_evaluations.find(params[:id])
|
||||
end
|
||||
end
|
@ -0,0 +1,20 @@
|
||||
class Ecs::CourseManagersController < Ecs::CourseBaseController
|
||||
skip_before_action :check_user_permission!, only: [:create, :destroy]
|
||||
before_action :check_major_manager_permission!, only: [:create, :destroy]
|
||||
|
||||
def create
|
||||
@user = Ecs::CreateCourseManagerService.call(current_course, params[:user_id])
|
||||
rescue Ecs::CreateCourseManagerService::Error => ex
|
||||
render_error(ex.message)
|
||||
end
|
||||
|
||||
def destroy
|
||||
# params[:id] 为 user_id
|
||||
manager = current_course.ec_course_users.find_by(user_id: params[:id])
|
||||
return render_error('不存在该课程管理员!') if manager.blank?
|
||||
|
||||
manager.destroy!
|
||||
|
||||
render_ok
|
||||
end
|
||||
end
|
@ -0,0 +1,30 @@
|
||||
class Ecs::CourseTargetsController < Ecs::CourseBaseController
|
||||
def index
|
||||
@course_targets = current_course.ec_course_targets.includes(:ec_graduation_subitems)
|
||||
|
||||
respond_to do |format|
|
||||
format.json
|
||||
format.xlsx do
|
||||
filename = "#{current_year.year}届_#{current_course.name}_课程目标_#{Time.current.strftime('%Y%m%d%H%M%S')}.xlsx"
|
||||
render xlsx: 'index', filename: filename
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
Ecs::CreateCourseTargetsService.call(current_course, create_params)
|
||||
@course_targets = current_course.ec_course_targets.includes(:ec_graduation_subitems)
|
||||
|
||||
render 'index'
|
||||
end
|
||||
|
||||
def with_achievement_methods
|
||||
@course_targets = current_course.ec_course_targets.includes(:ec_graduation_subitems, :ec_course_achievement_methods)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def create_params
|
||||
params.permit(course_targets: %i[id content standard_grade weight graduation_subitem_id])
|
||||
end
|
||||
end
|
@ -0,0 +1,75 @@
|
||||
class Ecs::EcCoursesController < Ecs::BaseController
|
||||
before_action :check_major_manager_permission!, only: [:create, :import, :destroy]
|
||||
|
||||
def index
|
||||
ec_courses = current_year.ec_courses
|
||||
|
||||
@count = ec_courses.count
|
||||
|
||||
@ec_courses = paginate ec_courses.includes(:course_managers)
|
||||
|
||||
course_ids = @ec_courses.map(&:id)
|
||||
# 课程目标数
|
||||
@target_count_map = EcCourseTarget.where(ec_course_id: course_ids).group(:ec_course_id).count
|
||||
# 考核方式数
|
||||
@evaluation_count_map = EcCourseEvaluation.where(ec_course_id: course_ids).group(:ec_course_id).count
|
||||
# 评价方法数
|
||||
@achievement_method_count_map = EcCourseAchievementMethod.where(ec_course_id: course_ids).group(:ec_course_id).count
|
||||
# 毕业目标数
|
||||
@graduation_subitem_count_map = EcGraduationSubitemCourseTarget.joins(:ec_course_target)
|
||||
.where(ec_course_targets: { ec_course_id: course_ids })
|
||||
.group('ec_course_targets.ec_course_id')
|
||||
.count('distinct ec_graduation_subitem_id')
|
||||
# 已达成毕业目标数
|
||||
@completed_subitem_count_map = EcCourseSupport.joins(:ec_graduation_requirement_calculation)
|
||||
.where(ec_course_id: course_ids)
|
||||
.where(ec_graduation_requirement_calculations: { status: 1 })
|
||||
.group('ec_course_supports.ec_course_id')
|
||||
.count('distinct ec_graduation_subitem_id')
|
||||
end
|
||||
|
||||
def search
|
||||
ec_courses = current_year.ec_courses
|
||||
|
||||
search = params[:search].to_s.strip
|
||||
if search
|
||||
ec_courses = ec_courses.where('name LIKE ?', "%#{search}%")
|
||||
end
|
||||
|
||||
@count = ec_courses.count
|
||||
@ec_courses = paginate ec_courses
|
||||
end
|
||||
|
||||
def create
|
||||
create_params = params.permit(:name)
|
||||
@ec_course = Ecs::CreateCourseService.call(current_year, create_params)
|
||||
rescue Ecs::CreateCourseService::Error => ex
|
||||
render_error(ex.message)
|
||||
end
|
||||
|
||||
def destroy
|
||||
current_course.destroy!
|
||||
render_ok
|
||||
end
|
||||
|
||||
def import
|
||||
success_count = Ecs::ImportCourseService.call(current_year, params[:attachment_id])
|
||||
render_ok(success_count: success_count)
|
||||
rescue Ecs::ImportCourseService::Error => ex
|
||||
render_error(ex.message)
|
||||
end
|
||||
|
||||
def link_course
|
||||
link_params = params.permit(:course_id)
|
||||
Ecs::LinkCourseService.call(current_course, link_params)
|
||||
render_ok
|
||||
rescue Ecs::LinkCourseService::Error => ex
|
||||
render_error(ex.message)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def current_course
|
||||
@_current_course ||= current_year.ec_courses.find(params[:id])
|
||||
end
|
||||
end
|
@ -0,0 +1,38 @@
|
||||
class Ecs::EcGraduationRequirementsController < Ecs::BaseController
|
||||
skip_before_action :check_user_permission!, only: [:create, :update]
|
||||
before_action :check_major_manager_permission!, only: [:create, :update]
|
||||
|
||||
def index
|
||||
@graduation_requirements = current_year.ec_graduation_requirements.includes(:ec_graduation_subitems)
|
||||
|
||||
respond_to do |format|
|
||||
format.json
|
||||
format.xlsx do
|
||||
filename = "#{current_year.year}届毕业要求及指导点_#{Time.current.strftime('%Y%m%d%H%M%S')}.xlsx"
|
||||
render xlsx: 'index', filename: filename
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
graduation_requirement = current_year.graduation_requirements.new
|
||||
@graduation_requirement = Ecs::SaveGraduationRequirementeService.call(graduation_requirement, create_params)
|
||||
render 'show'
|
||||
end
|
||||
|
||||
def update
|
||||
graduation_requirement = current_year.graduation_requirements.find(params[:id])
|
||||
@graduation_requirement = Ecs::SaveGraduationRequirementeService.call(graduation_requirement, update_params)
|
||||
render 'show'
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def create_params
|
||||
params.permit(:position, :content, graduation_subitems: [:content])
|
||||
end
|
||||
|
||||
def update_params
|
||||
params.permit(:position, :content, graduation_subitems: [:id, :content])
|
||||
end
|
||||
end
|
@ -0,0 +1,56 @@
|
||||
class Ecs::EcMajorSchoolsController < Ecs::BaseController
|
||||
def index
|
||||
major_schools = current_school.ec_major_schools.not_template
|
||||
|
||||
# 专业/课程管理员,则仅显示他们所在的专业
|
||||
if major_or_course_manager?
|
||||
ec_major_school_ids = current_user.ec_major_school_users.pluck(:ec_major_school_id)
|
||||
|
||||
ec_course_major_subquery = current_user.ec_course_users.select(:ec_year_id)
|
||||
ec_year_school_ids = EcYear.where(id: ec_course_major_subquery).pluck(:ec_major_school_id)
|
||||
|
||||
major_schools = major_schools.where(id: (ec_major_school_ids + ec_year_school_ids).uniq)
|
||||
end
|
||||
|
||||
if params[:search].present?
|
||||
major_ids_subquery = EcMajor.search_name_or_code(params[:search]).select(:id)
|
||||
major_schools = major_schools.where(ec_major_id: major_ids_subquery)
|
||||
end
|
||||
|
||||
@count = major_schools.count #检索后的数量,小于或等于全部数量
|
||||
@major_schools = paginate(major_schools.includes(:users, :ec_major))
|
||||
|
||||
@template_major_school = current_school.ec_major_schools.is_template.first #示例专业
|
||||
end
|
||||
|
||||
def create
|
||||
ActiveRecord::Base.transaction do
|
||||
Array(params[:major_ids].presence).each do |id|
|
||||
EcMajorSchool.create!(ec_major_id: id, school_id: current_school.id)
|
||||
end
|
||||
end
|
||||
|
||||
render_ok
|
||||
end
|
||||
|
||||
def destroy
|
||||
return render_forbidden if major_or_course_manager?
|
||||
|
||||
major_school = current_school.ec_major_schools.find(params[:id])
|
||||
|
||||
if major_school.template_major?
|
||||
render_error('示例专业不能被删除')
|
||||
return
|
||||
end
|
||||
|
||||
major_school.destroy!
|
||||
|
||||
render_ok
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def current_school
|
||||
@_current_school ||= School.find(params[:school_id])
|
||||
end
|
||||
end
|
@ -0,0 +1,19 @@
|
||||
class Ecs::EcMajorsController < Ecs::BaseController
|
||||
def index
|
||||
school_major_subquery = current_school.ec_major_schools.select(:ec_major_id) #学校已选择的专业
|
||||
ec_majors = EcMajor.where.not(id: school_major_subquery)
|
||||
|
||||
if params[:search].present?
|
||||
ec_majors = ec_majors.search_name_or_code(params[:search])
|
||||
end
|
||||
|
||||
@count = ec_majors.count
|
||||
@ec_majors = paginate(ec_majors)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def current_school
|
||||
@_current_school ||= School.find(params[:school_id])
|
||||
end
|
||||
end
|
@ -0,0 +1,26 @@
|
||||
class Ecs::EcTrainingObjectivesController < Ecs::BaseController
|
||||
before_action :check_major_manager_permission!, only: [:create]
|
||||
|
||||
def show
|
||||
@training_objective = current_year.ec_training_objective
|
||||
|
||||
respond_to do |format|
|
||||
format.json
|
||||
format.xlsx do
|
||||
filename = "#{@training_objective.ec_year.year}届培养目标_#{Time.current.strftime('%Y%m%d%H%M%S')}.xlsx"
|
||||
render xlsx: 'show', filename: filename
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
@training_objective = Ecs::CreateTrainingObjectiveService.call(current_year, create_params)
|
||||
render 'show'
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def create_params
|
||||
params.permit(:content, training_subitems: [:id, :content])
|
||||
end
|
||||
end
|
@ -0,0 +1,17 @@
|
||||
class Ecs::EvaluationsController < Ecs::CourseBaseController
|
||||
def show
|
||||
service = Ecs::QueryCourseEvaluationService.new(current_course)
|
||||
|
||||
render_ok(
|
||||
course_targets: service.course_targets,
|
||||
course_achievement: service.course_achievement,
|
||||
graduation_subitem_evaluations: service.graduation_subitem_evaluations,
|
||||
score_levels_map: service.score_levels_map
|
||||
)
|
||||
end
|
||||
|
||||
def create
|
||||
Ecs::CalculateCourseEvaluationService.call(current_course)
|
||||
render_ok
|
||||
end
|
||||
end
|
@ -0,0 +1,28 @@
|
||||
class Ecs::GraduationCourseSupportsController < Ecs::BaseController
|
||||
before_action :check_major_manager_permission!, only: [:create]
|
||||
|
||||
def show
|
||||
@graduation_subitems = current_year.ec_graduation_subitems
|
||||
.includes(:ec_graduation_requirement, ec_course_supports: :ec_course)
|
||||
@course_count = current_year.ec_courses.count
|
||||
|
||||
respond_to do |format|
|
||||
format.json
|
||||
format.xlsx do
|
||||
filename = "#{current_year.year}届课程体系对毕业要求的支撑_#{Time.current.strftime('%Y%m%d%H%M%S')}.xlsx"
|
||||
render xlsx: 'show', filename: filename
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
graduation_subitem = current_year.ec_graduation_subitems.find(params[:graduation_subitem_id])
|
||||
@graduation_subitem = Ecs::SaveGraduationCourseSupportsService.call(graduation_subitem, create_params)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def create_params
|
||||
params.permit(course_supports: %i[id ec_course_id weights top_relation])
|
||||
end
|
||||
end
|
@ -0,0 +1,11 @@
|
||||
class Ecs::HomesController < Ecs::BaseController
|
||||
def index
|
||||
@school_managers = current_school.users
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def current_school
|
||||
@_current_school ||= School.find(params[:school_id])
|
||||
end
|
||||
end
|
@ -0,0 +1,30 @@
|
||||
class Ecs::MajorManagersController < Ecs::BaseController
|
||||
skip_before_action :check_user_permission!
|
||||
before_action :check_manager_permission!
|
||||
|
||||
def create
|
||||
@user = Ecs::CreateMajorManagerService.call(current_major_school, params[:user_id])
|
||||
rescue Ecs::CreateMajorManagerService::Error => ex
|
||||
render_error(ex.message)
|
||||
end
|
||||
|
||||
def destroy
|
||||
# params[:id] 为 user_id
|
||||
manager = current_major_school.ec_major_school_users.find_by(user_id: params[:id])
|
||||
return render_error('不存在该专业管理员!') if manager.blank?
|
||||
|
||||
manager.destroy!
|
||||
|
||||
render_ok
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def current_major_school
|
||||
@_ec_major_school ||= EcMajorSchool.find(params[:ec_major_school_id])
|
||||
end
|
||||
|
||||
def current_school
|
||||
@_current_school ||= current_major_school.school
|
||||
end
|
||||
end
|
@ -0,0 +1,16 @@
|
||||
class ReachCriteriaController < Ecs::BaseController
|
||||
before_action :check_major_manager_permission!, only: [:create]
|
||||
|
||||
def create
|
||||
reach_criteria = params[:reach_criteria].to_f
|
||||
|
||||
if reach_criteria.zero?
|
||||
render_error('必须大于0')
|
||||
return
|
||||
end
|
||||
|
||||
current_year.update!(calculation_value: reach_criteria)
|
||||
|
||||
render_ok
|
||||
end
|
||||
end
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue