Compare commits
No commits in common. "master" and "feature" have entirely different histories.
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
# Ignore lock config file
|
# Ignore lock config file
|
||||||
*.log
|
*.log
|
||||||
.env
|
|
||||||
# mac
|
# mac
|
||||||
*.DS_Store
|
*.DS_Store
|
||||||
.bashrc
|
.bashrc
|
||||||
|
@ -81,8 +81,7 @@ db/bak/
|
||||||
docker/
|
docker/
|
||||||
educoder.sql
|
educoder.sql
|
||||||
redis_data/
|
redis_data/
|
||||||
|
Dockerfile
|
||||||
dump.rdb
|
dump.rdb
|
||||||
.tags*
|
.tags*
|
||||||
ceshi_user.xlsx
|
ceshi_user.xlsx
|
||||||
public/trace_task_results
|
|
||||||
public/项目活跃度排行.xls
|
|
59
Dockerfile
59
Dockerfile
|
@ -1,59 +0,0 @@
|
||||||
FROM ubuntu:20.04
|
|
||||||
RUN apt-get update
|
|
||||||
|
|
||||||
RUN DEBIAN_FRONTEND=noninteractive apt install -y tzdata
|
|
||||||
# basics
|
|
||||||
RUN apt-get install -y libssl-dev curl libmysqlclient-dev imagemagick nodejs mysql-server redis-server
|
|
||||||
RUN ln -fs /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
|
|
||||||
# confirm openssl version
|
|
||||||
RUN openssl version
|
|
||||||
RUN which openssl
|
|
||||||
# install RVM, Ruby, and Bundler
|
|
||||||
RUN \curl -L https://get.rvm.io | bash -s stable
|
|
||||||
# rvm environment variable
|
|
||||||
RUN /bin/bash -l -c "source /etc/profile.d/rvm.sh"
|
|
||||||
RUN /bin/bash -l -c "rvm requirements"
|
|
||||||
# replace ruby mirror url, accelerate install ruby
|
|
||||||
RUN sed -i 's/rvm_remote_server_url2/#rvm_remote_server_url2/g' /usr/local/rvm/config/db
|
|
||||||
RUN sed -i 's/cache.ruby-lang.org/cache.ruby-china.com/g' /usr/local/rvm/config/db
|
|
||||||
# install ruby
|
|
||||||
RUN /bin/bash -l -c "rvm install 2.4.5"
|
|
||||||
# confirm ruby version
|
|
||||||
RUN /bin/bash -l -c "rvm list"
|
|
||||||
RUN /bin/bash -l -c "ruby -v"
|
|
||||||
|
|
||||||
#RUN apt-get install -y nodejs
|
|
||||||
|
|
||||||
WORKDIR /home/app/gitlink
|
|
||||||
|
|
||||||
ADD ./ /home/app/gitlink
|
|
||||||
|
|
||||||
RUN cd /home/app/gitlink
|
|
||||||
|
|
||||||
RUN /bin/bash -l -c 'gem sources --add https://gems.ruby-china.com/ --remove https://rubygems.org/'
|
|
||||||
|
|
||||||
RUN /bin/bash -l -c 'gem update --system'
|
|
||||||
|
|
||||||
RUN /bin/bash -l -c 'gem install bundler -v 2.3.26'
|
|
||||||
RUN /bin/bash -l -c 'gem install rake'
|
|
||||||
RUN /bin/bash -l -c 'gem install puma -v 5.6.5'
|
|
||||||
|
|
||||||
RUN rm -rf Gemfile.lock
|
|
||||||
|
|
||||||
RUN cp config/configuration.yml.example config/configuration.yml
|
|
||||||
RUN cp config/database-docker.yml.example config/database.yml
|
|
||||||
RUN touch config/redis.yml
|
|
||||||
RUN touch config/elasticsearch.yml
|
|
||||||
|
|
||||||
RUN /bin/bash -l -c 'bundle install'
|
|
||||||
|
|
||||||
RUN redis-server &
|
|
||||||
|
|
||||||
RUN /bin/bash -l -c 'bundle exec rake sync_table_structure:import_csv'
|
|
||||||
|
|
||||||
RUN /bin/bash -l -c 'rails db:migrate RAILS_ENV=development'
|
|
||||||
|
|
||||||
RUN /bin/bash -l -c 'bundle exec sidekiq -C config/sidekiq.yml -e production -d'
|
|
||||||
|
|
||||||
EXPOSE 4000
|
|
||||||
RUN /bin/bash -l -c 'RAILS_ENV=production puma -C config/puma.rb'
|
|
|
@ -1,19 +0,0 @@
|
||||||
FROM ubuntu:20.04
|
|
||||||
RUN apt-get update
|
|
||||||
# basics
|
|
||||||
RUN apt-get install -y libssl-dev curl libmysqlclient-dev imagemagick nodejs mysql-server redis-server tzdata
|
|
||||||
RUN ln -fs /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
|
|
||||||
# confirm openssl version
|
|
||||||
RUN openssl version
|
|
||||||
RUN which openssl
|
|
||||||
# install RVM, Ruby, and Bundler
|
|
||||||
RUN \curl -L https://get.rvm.io | bash -s stable
|
|
||||||
RUN /bin/bash -l -c "rvm requirements"
|
|
||||||
# replace ruby mirror url, accelerate install ruby
|
|
||||||
RUN sed -i 's/rvm_remote_server_url2/#rvm_remote_server_url2/g' /usr/local/rvm/config/db
|
|
||||||
RUN sed -i 's/cache.ruby-lang.org/cache.ruby-china.com/g' /usr/local/rvm/config/db
|
|
||||||
# install ruby
|
|
||||||
RUN /bin/bash -l -c "rvm install 2.4.5"
|
|
||||||
# confirm ruby version
|
|
||||||
RUN /bin/bash -l -c "rvm list"
|
|
||||||
RUN /bin/bash -l -c "ruby -v"
|
|
274
Gemfile
274
Gemfile
|
@ -1,144 +1,130 @@
|
||||||
#source 'https://gems.ruby-china.com'
|
source 'https://gems.ruby-china.com'
|
||||||
source 'https://mirrors.cloud.tencent.com/rubygems/'
|
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
|
||||||
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
|
|
||||||
|
gem 'rails', '~> 5.2.0'
|
||||||
gem 'rails', '~> 5.2.0'
|
gem 'mysql2', '>= 0.4.4', '< 0.6.0'
|
||||||
gem 'mysql2', '>= 0.4.4', '< 0.6.0'
|
gem 'puma', '~> 3.11'
|
||||||
gem 'puma', '~> 5.6.5'
|
gem 'sass-rails', '~> 5.0'
|
||||||
gem 'sass-rails', '~> 5.0'
|
gem 'uglifier', '>= 1.3.0'
|
||||||
gem 'uglifier', '>= 1.3.0'
|
|
||||||
|
# gem 'coffee-rails', '~> 4.2'
|
||||||
# gem 'coffee-rails', '~> 4.2'
|
gem 'turbolinks', '~> 5'
|
||||||
gem 'turbolinks', '~> 5'
|
gem 'jbuilder', '~> 2.5'
|
||||||
gem 'jbuilder', '~> 2.5'
|
gem 'groupdate', '~> 4.1.0'
|
||||||
gem 'groupdate', '~> 4.1.0'
|
gem 'chartkick'
|
||||||
gem 'chartkick'
|
gem 'grape-entity', '~> 0.7.1'
|
||||||
gem 'grape-entity', '~> 0.7.1'
|
gem 'kaminari', '~> 1.1', '>= 1.1.1'
|
||||||
gem 'kaminari', '~> 1.1', '>= 1.1.1'
|
|
||||||
|
gem 'bootsnap', '>= 1.1.0', require: false
|
||||||
gem 'bootsnap', '>= 1.1.0', require: false
|
|
||||||
|
gem 'chinese_pinyin'
|
||||||
gem 'chinese_pinyin'
|
|
||||||
|
gem 'rack-cors'
|
||||||
gem 'rack-cors'
|
gem 'redis-rails'
|
||||||
gem 'redis-rails'
|
gem 'roo-xls'
|
||||||
gem 'roo-xls'
|
gem 'simple_xlsx_reader'
|
||||||
gem 'simple_xlsx_reader', '~>1.0.4'
|
|
||||||
|
gem 'rubyzip'
|
||||||
gem 'rubyzip'
|
|
||||||
|
gem 'spreadsheet'
|
||||||
gem 'spreadsheet'
|
gem 'ruby-ole'
|
||||||
gem 'ruby-ole'
|
# 导出为xlsx
|
||||||
# 导出为xlsx
|
gem 'axlsx', '~> 3.0.0.pre'
|
||||||
gem 'axlsx', '~> 3.0.0.pre'
|
gem 'axlsx_rails', '~> 0.5.2'
|
||||||
gem 'axlsx_rails', '~> 0.5.2'
|
|
||||||
|
gem 'oauth2'
|
||||||
gem 'oauth2'
|
#导出为pdf
|
||||||
#导出为pdf
|
gem 'pdfkit'
|
||||||
gem 'pdfkit'
|
gem 'wkhtmltopdf-binary'
|
||||||
gem 'wkhtmltopdf-binary'
|
# gem 'request_store'
|
||||||
# gem 'request_store'
|
#gem 'iconv'
|
||||||
#gem 'iconv'
|
# markdown 转html
|
||||||
# markdown 转html
|
gem 'redcarpet', '~> 3.4'
|
||||||
gem 'redcarpet', '~> 3.4'
|
|
||||||
|
gem 'rqrcode', '~> 0.10.1'
|
||||||
gem 'rqrcode', '~> 0.10.1'
|
gem 'rqrcode_png'
|
||||||
gem 'rqrcode_png'
|
|
||||||
|
gem 'acts-as-taggable-on', '~> 6.0'
|
||||||
gem 'acts-as-taggable-on', '~> 6.0'
|
|
||||||
|
# a tree structure
|
||||||
# a tree structure
|
gem 'ancestry'
|
||||||
gem 'ancestry'
|
gem 'acts_as_list'
|
||||||
gem 'acts_as_list'
|
gem 'omniauth-cas'
|
||||||
gem 'omniauth-cas'
|
|
||||||
|
# profiler Middleware
|
||||||
# profiler Middleware
|
gem 'rack-mini-profiler'
|
||||||
# gem 'rack-mini-profiler'
|
|
||||||
|
# object-based searching
|
||||||
# object-based searching
|
gem 'ransack'
|
||||||
gem 'ransack'
|
|
||||||
|
group :development, :test do
|
||||||
group :development, :test do
|
gem 'rspec-rails', '~> 3.8'
|
||||||
gem 'rspec-rails', '~> 3.8'
|
end
|
||||||
end
|
|
||||||
|
group :development do
|
||||||
group :development do
|
gem 'prettier'
|
||||||
gem 'prettier'
|
gem 'rubocop', '~> 0.52.0'
|
||||||
gem 'rubocop', '~> 0.52.0'
|
gem 'solargraph', '~> 0.38.0'
|
||||||
gem 'solargraph', '~> 0.38.0'
|
gem 'awesome_print'
|
||||||
gem 'awesome_print'
|
gem 'web-console', '>= 3.3.0'
|
||||||
gem 'web-console', '>= 3.3.0'
|
gem 'listen', '>= 3.0.5', '< 3.2'
|
||||||
gem 'listen', '>= 3.0.5', '< 3.2'
|
gem 'spring'
|
||||||
gem 'spring'
|
gem 'spring-watcher-listen', '~> 2.0.0'
|
||||||
gem 'spring-watcher-listen', '~> 2.0.0'
|
gem "annotate", "~> 2.6.0"
|
||||||
gem "annotate", "~> 2.6.0"
|
end
|
||||||
end
|
|
||||||
|
group :test do
|
||||||
group :test do
|
gem 'capybara', '>= 2.15', '< 4.0'
|
||||||
gem 'capybara', '>= 2.15', '< 4.0'
|
gem 'selenium-webdriver'
|
||||||
gem 'selenium-webdriver'
|
gem 'chromedriver-helper'
|
||||||
gem 'chromedriver-helper'
|
end
|
||||||
end
|
|
||||||
|
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
|
||||||
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
|
|
||||||
|
#编码检测
|
||||||
#编码检测
|
gem 'rchardet', '~> 1.8'
|
||||||
gem 'rchardet', '~> 1.8'
|
|
||||||
|
# http client
|
||||||
# http client
|
gem 'faraday', '~> 0.15.4'
|
||||||
gem 'faraday', '~> 0.15.4'
|
|
||||||
|
# view
|
||||||
# view
|
gem 'active_decorator'
|
||||||
gem 'active_decorator'
|
gem 'bootstrap', '~> 4.3.1'
|
||||||
gem 'bootstrap', '~> 4.3.1'
|
gem 'jquery-rails'
|
||||||
gem 'jquery-rails'
|
gem 'simple_form'
|
||||||
gem 'simple_form'
|
gem 'font-awesome-sass', '4.7.0'
|
||||||
gem 'font-awesome-sass', '4.7.0'
|
|
||||||
|
# i18n
|
||||||
# i18n
|
gem 'rails-i18n', '~> 5.1'
|
||||||
gem 'rails-i18n', '~> 5.1'
|
|
||||||
|
# job
|
||||||
# job
|
gem 'sidekiq'
|
||||||
gem 'sidekiq',"5.2.8"
|
gem 'sinatra'
|
||||||
gem 'sinatra'
|
gem "sidekiq-cron", "~> 1.1"
|
||||||
gem "sidekiq-cron", "1.2.0"
|
|
||||||
gem 'sidekiq-failures'
|
# batch insert
|
||||||
|
gem 'bulk_insert'
|
||||||
# batch insert
|
|
||||||
gem 'bulk_insert'
|
# elasticsearch
|
||||||
|
gem 'searchkick'
|
||||||
# elasticsearch
|
|
||||||
gem 'searchkick'
|
gem 'aasm'
|
||||||
|
gem 'enumerize'
|
||||||
gem 'aasm'
|
|
||||||
gem 'enumerize'
|
gem 'diffy'
|
||||||
|
|
||||||
gem 'diffy'
|
gem 'deep_cloneable', '~> 3.0.0'
|
||||||
|
|
||||||
gem 'deep_cloneable', '~> 3.0.0'
|
# oauth2
|
||||||
|
gem 'omniauth', '~> 1.9.0'
|
||||||
# oauth2
|
gem 'omniauth-oauth2', '~> 1.6.0'
|
||||||
gem 'omniauth', '~> 1.9.0'
|
|
||||||
gem 'omniauth-oauth2', '~> 1.6.0'
|
# global var
|
||||||
gem "omniauth-github"
|
gem 'request_store'
|
||||||
gem "omniauth-rails_csrf_protection"
|
|
||||||
gem 'omniauth-gitee', '~> 1.0.0'
|
# 敏感词汇
|
||||||
gem "omniauth-wechat-oauth2"
|
gem 'harmonious_dictionary', '~> 0.0.1'
|
||||||
|
|
||||||
# global var
|
gem 'parallel', '~> 1.19', '>= 1.19.1'
|
||||||
gem 'request_store'
|
|
||||||
|
gem 'letter_avatar'
|
||||||
# 敏感词汇
|
|
||||||
gem 'harmonious_dictionary', '~> 0.0.1'
|
|
||||||
|
|
||||||
gem 'parallel', '~> 1.19', '>= 1.19.1'
|
|
||||||
|
|
||||||
gem 'letter_avatar'
|
|
||||||
|
|
||||||
gem 'jwt'
|
|
||||||
|
|
||||||
gem 'doorkeeper'
|
|
||||||
|
|
||||||
gem 'doorkeeper-jwt'
|
|
||||||
|
|
||||||
gem 'gitea-client', '~> 1.5.8'
|
|
||||||
|
|
62
Gemfile.lock
62
Gemfile.lock
|
@ -1,5 +1,5 @@
|
||||||
GEM
|
GEM
|
||||||
remote: https://mirrors.cloud.tencent.com/rubygems/
|
remote: https://gems.ruby-china.com/
|
||||||
specs:
|
specs:
|
||||||
aasm (5.0.6)
|
aasm (5.0.6)
|
||||||
concurrent-ruby (~> 1.0)
|
concurrent-ruby (~> 1.0)
|
||||||
|
@ -106,12 +106,6 @@ GEM
|
||||||
activerecord (>= 3.1.0, < 7)
|
activerecord (>= 3.1.0, < 7)
|
||||||
diff-lcs (1.3)
|
diff-lcs (1.3)
|
||||||
diffy (3.3.0)
|
diffy (3.3.0)
|
||||||
domain_name (0.5.20190701)
|
|
||||||
unf (>= 0.0.5, < 1.0.0)
|
|
||||||
doorkeeper (5.5.1)
|
|
||||||
railties (>= 5)
|
|
||||||
doorkeeper-jwt (0.4.1)
|
|
||||||
jwt (>= 2.1)
|
|
||||||
e2mmap (0.1.0)
|
e2mmap (0.1.0)
|
||||||
elasticsearch (7.5.0)
|
elasticsearch (7.5.0)
|
||||||
elasticsearch-api (= 7.5.0)
|
elasticsearch-api (= 7.5.0)
|
||||||
|
@ -135,8 +129,6 @@ GEM
|
||||||
fugit (1.4.1)
|
fugit (1.4.1)
|
||||||
et-orbi (~> 1.1, >= 1.1.8)
|
et-orbi (~> 1.1, >= 1.1.8)
|
||||||
raabro (~> 1.4)
|
raabro (~> 1.4)
|
||||||
gitea-client (1.4.2)
|
|
||||||
rest-client (~> 2.1.0)
|
|
||||||
globalid (0.4.2)
|
globalid (0.4.2)
|
||||||
activesupport (>= 4.2.0)
|
activesupport (>= 4.2.0)
|
||||||
grape-entity (0.7.1)
|
grape-entity (0.7.1)
|
||||||
|
@ -147,9 +139,6 @@ GEM
|
||||||
harmonious_dictionary (0.0.1)
|
harmonious_dictionary (0.0.1)
|
||||||
hashie (3.6.0)
|
hashie (3.6.0)
|
||||||
htmlentities (4.3.4)
|
htmlentities (4.3.4)
|
||||||
http-accept (1.7.0)
|
|
||||||
http-cookie (1.0.5)
|
|
||||||
domain_name (~> 0.5)
|
|
||||||
i18n (1.8.2)
|
i18n (1.8.2)
|
||||||
concurrent-ruby (~> 1.0)
|
concurrent-ruby (~> 1.0)
|
||||||
io-like (0.3.1)
|
io-like (0.3.1)
|
||||||
|
@ -187,9 +176,6 @@ GEM
|
||||||
mimemagic (~> 0.3.2)
|
mimemagic (~> 0.3.2)
|
||||||
maruku (0.7.3)
|
maruku (0.7.3)
|
||||||
method_source (0.9.2)
|
method_source (0.9.2)
|
||||||
mime-types (3.4.1)
|
|
||||||
mime-types-data (~> 3.2015)
|
|
||||||
mime-types-data (3.2023.0218.1)
|
|
||||||
mimemagic (0.3.10)
|
mimemagic (0.3.10)
|
||||||
nokogiri (~> 1)
|
nokogiri (~> 1)
|
||||||
rake
|
rake
|
||||||
|
@ -203,7 +189,6 @@ GEM
|
||||||
mustermann (1.1.1)
|
mustermann (1.1.1)
|
||||||
ruby2_keywords (~> 0.0.1)
|
ruby2_keywords (~> 0.0.1)
|
||||||
mysql2 (0.5.3)
|
mysql2 (0.5.3)
|
||||||
netrc (0.11.0)
|
|
||||||
nio4r (2.5.2)
|
nio4r (2.5.2)
|
||||||
nokogiri (1.10.8)
|
nokogiri (1.10.8)
|
||||||
mini_portile2 (~> 2.4.0)
|
mini_portile2 (~> 2.4.0)
|
||||||
|
@ -220,21 +205,9 @@ GEM
|
||||||
addressable (~> 2.3)
|
addressable (~> 2.3)
|
||||||
nokogiri (~> 1.5)
|
nokogiri (~> 1.5)
|
||||||
omniauth (~> 1.2)
|
omniauth (~> 1.2)
|
||||||
omniauth-gitee (1.0.0)
|
|
||||||
omniauth (>= 1.5, < 3.0)
|
|
||||||
omniauth-oauth2 (>= 1.4.0, < 2.0)
|
|
||||||
omniauth-github (1.4.0)
|
|
||||||
omniauth (~> 1.5)
|
|
||||||
omniauth-oauth2 (>= 1.4.0, < 2.0)
|
|
||||||
omniauth-oauth2 (1.6.0)
|
omniauth-oauth2 (1.6.0)
|
||||||
oauth2 (~> 1.1)
|
oauth2 (~> 1.1)
|
||||||
omniauth (~> 1.9)
|
omniauth (~> 1.9)
|
||||||
omniauth-rails_csrf_protection (0.1.2)
|
|
||||||
actionpack (>= 4.2)
|
|
||||||
omniauth (>= 1.3.1)
|
|
||||||
omniauth-wechat-oauth2 (0.2.2)
|
|
||||||
omniauth (>= 1.3.2)
|
|
||||||
omniauth-oauth2 (>= 1.1.1)
|
|
||||||
parallel (1.19.1)
|
parallel (1.19.1)
|
||||||
parser (2.7.1.1)
|
parser (2.7.1.1)
|
||||||
ast (~> 2.4.0)
|
ast (~> 2.4.0)
|
||||||
|
@ -245,12 +218,13 @@ GEM
|
||||||
powerpack (0.1.2)
|
powerpack (0.1.2)
|
||||||
prettier (0.18.2)
|
prettier (0.18.2)
|
||||||
public_suffix (4.0.3)
|
public_suffix (4.0.3)
|
||||||
puma (5.6.5)
|
puma (3.12.2)
|
||||||
nio4r (~> 2.0)
|
|
||||||
raabro (1.4.0)
|
raabro (1.4.0)
|
||||||
rack (2.0.9)
|
rack (2.0.9)
|
||||||
rack-cors (1.1.1)
|
rack-cors (1.1.1)
|
||||||
rack (>= 2.0.0)
|
rack (>= 2.0.0)
|
||||||
|
rack-mini-profiler (2.0.1)
|
||||||
|
rack (>= 1.2.0)
|
||||||
rack-protection (2.0.8.1)
|
rack-protection (2.0.8.1)
|
||||||
rack
|
rack
|
||||||
rack-test (1.1.0)
|
rack-test (1.1.0)
|
||||||
|
@ -314,11 +288,6 @@ GEM
|
||||||
regexp_parser (1.7.0)
|
regexp_parser (1.7.0)
|
||||||
request_store (1.5.0)
|
request_store (1.5.0)
|
||||||
rack (>= 1.4)
|
rack (>= 1.4)
|
||||||
rest-client (2.1.0)
|
|
||||||
http-accept (>= 1.7.0, < 2.0)
|
|
||||||
http-cookie (>= 1.0.2, < 2.0)
|
|
||||||
mime-types (>= 1.16, < 4.0)
|
|
||||||
netrc (~> 0.8)
|
|
||||||
reverse_markdown (1.4.0)
|
reverse_markdown (1.4.0)
|
||||||
nokogiri
|
nokogiri
|
||||||
roo (2.8.3)
|
roo (2.8.3)
|
||||||
|
@ -396,8 +365,6 @@ GEM
|
||||||
sidekiq-cron (1.2.0)
|
sidekiq-cron (1.2.0)
|
||||||
fugit (~> 1.1)
|
fugit (~> 1.1)
|
||||||
sidekiq (>= 4.2.1)
|
sidekiq (>= 4.2.1)
|
||||||
sidekiq-failures (1.0.4)
|
|
||||||
sidekiq (>= 4.0.0)
|
|
||||||
simple_form (5.0.2)
|
simple_form (5.0.2)
|
||||||
actionpack (>= 5.0)
|
actionpack (>= 5.0)
|
||||||
activemodel (>= 5.0)
|
activemodel (>= 5.0)
|
||||||
|
@ -447,9 +414,6 @@ GEM
|
||||||
thread_safe (~> 0.1)
|
thread_safe (~> 0.1)
|
||||||
uglifier (4.2.0)
|
uglifier (4.2.0)
|
||||||
execjs (>= 0.3.0, < 3)
|
execjs (>= 0.3.0, < 3)
|
||||||
unf (0.1.4)
|
|
||||||
unf_ext
|
|
||||||
unf_ext (0.0.8.2)
|
|
||||||
unicode-display_width (1.6.1)
|
unicode-display_width (1.6.1)
|
||||||
web-console (3.7.0)
|
web-console (3.7.0)
|
||||||
actionview (>= 5.0)
|
actionview (>= 5.0)
|
||||||
|
@ -486,18 +450,14 @@ DEPENDENCIES
|
||||||
chromedriver-helper
|
chromedriver-helper
|
||||||
deep_cloneable (~> 3.0.0)
|
deep_cloneable (~> 3.0.0)
|
||||||
diffy
|
diffy
|
||||||
doorkeeper
|
|
||||||
doorkeeper-jwt
|
|
||||||
enumerize
|
enumerize
|
||||||
faraday (~> 0.15.4)
|
faraday (~> 0.15.4)
|
||||||
font-awesome-sass (= 4.7.0)
|
font-awesome-sass (= 4.7.0)
|
||||||
gitea-client (~> 1.4.2)
|
|
||||||
grape-entity (~> 0.7.1)
|
grape-entity (~> 0.7.1)
|
||||||
groupdate (~> 4.1.0)
|
groupdate (~> 4.1.0)
|
||||||
harmonious_dictionary (~> 0.0.1)
|
harmonious_dictionary (~> 0.0.1)
|
||||||
jbuilder (~> 2.5)
|
jbuilder (~> 2.5)
|
||||||
jquery-rails
|
jquery-rails
|
||||||
jwt
|
|
||||||
kaminari (~> 1.1, >= 1.1.1)
|
kaminari (~> 1.1, >= 1.1.1)
|
||||||
letter_avatar
|
letter_avatar
|
||||||
listen (>= 3.0.5, < 3.2)
|
listen (>= 3.0.5, < 3.2)
|
||||||
|
@ -505,16 +465,13 @@ DEPENDENCIES
|
||||||
oauth2
|
oauth2
|
||||||
omniauth (~> 1.9.0)
|
omniauth (~> 1.9.0)
|
||||||
omniauth-cas
|
omniauth-cas
|
||||||
omniauth-gitee (~> 1.0.0)
|
|
||||||
omniauth-github
|
|
||||||
omniauth-oauth2 (~> 1.6.0)
|
omniauth-oauth2 (~> 1.6.0)
|
||||||
omniauth-rails_csrf_protection
|
|
||||||
omniauth-wechat-oauth2
|
|
||||||
parallel (~> 1.19, >= 1.19.1)
|
parallel (~> 1.19, >= 1.19.1)
|
||||||
pdfkit
|
pdfkit
|
||||||
prettier
|
prettier
|
||||||
puma (~> 5.6.5)
|
puma (~> 3.11)
|
||||||
rack-cors
|
rack-cors
|
||||||
|
rack-mini-profiler
|
||||||
rails (~> 5.2.0)
|
rails (~> 5.2.0)
|
||||||
rails-i18n (~> 5.1)
|
rails-i18n (~> 5.1)
|
||||||
ransack
|
ransack
|
||||||
|
@ -532,11 +489,10 @@ DEPENDENCIES
|
||||||
sass-rails (~> 5.0)
|
sass-rails (~> 5.0)
|
||||||
searchkick
|
searchkick
|
||||||
selenium-webdriver
|
selenium-webdriver
|
||||||
sidekiq (= 5.2.8)
|
sidekiq
|
||||||
sidekiq-cron (= 1.2.0)
|
sidekiq-cron (~> 1.1)
|
||||||
sidekiq-failures
|
|
||||||
simple_form
|
simple_form
|
||||||
simple_xlsx_reader (~> 1.0.4)
|
simple_xlsx_reader
|
||||||
sinatra
|
sinatra
|
||||||
solargraph (~> 0.38.0)
|
solargraph (~> 0.38.0)
|
||||||
spreadsheet
|
spreadsheet
|
||||||
|
|
106
README.md
106
README.md
|
@ -3,14 +3,13 @@
|
||||||
GitLink(确实开源)是中国计算机学会(CCF)官方指定的开源创新服务平台,旨在以“为开源创新服务”为使命,以“成为开源创新的汇聚地”为愿景,秉承“创新、开放、协作、共享”的价值观,致力于为大规模开源开放协同创新助力赋能,打造创新成果孵化和新工科人才培养的开源创新生态!
|
GitLink(确实开源)是中国计算机学会(CCF)官方指定的开源创新服务平台,旨在以“为开源创新服务”为使命,以“成为开源创新的汇聚地”为愿景,秉承“创新、开放、协作、共享”的价值观,致力于为大规模开源开放协同创新助力赋能,打造创新成果孵化和新工科人才培养的开源创新生态!
|
||||||
|
|
||||||
<center>
|
<center>
|
||||||
<img src="docs/figs/gitlink.png" width=80% /></center>
|
<img src="https://code.gitlink.org.cn/young/forgeplus/raw/branch/master/docs/figs/gitlink.png?raw=true" width=80% /></center>
|
||||||
|
|
||||||
|
|
||||||
## 特色功能
|
## 特色功能
|
||||||
|
|
||||||
- **分布式协作开发**:基于Git打造分布式代码托管环境,提供免费公、私有代码仓库,支持在线文件编辑、代码分支管理、协作贡献统计、代码仓库复刻(Fork)、贡献合并请求(PR)、群智贡献审阅等功能,让您的项目在这里健康、快速的成长!
|
- **分布式协作开发**:基于Git打造分布式代码托管环境,提供免费公、私有代码仓库,支持在线文件编辑、代码分支管理、协作贡献统计、代码仓库复刻(Fork)、贡献合并请求(PR)、群智贡献审阅等功能,让您的项目在这里健康、快速的成长!
|
||||||
|
|
||||||
- **一站式过程管理**:提供疑修(Issue)、里程碑、通知提醒、标签归档等多样化任务管理工具,支持各类开发任务的发布、指派与跟踪,同时提供在线Wiki文档、组织多粒度管理等功能,为您搭建一站式的项目过程管理环境,让您的团队协作更高效、过程更透明!
|
- **一站式过程管理**:提供易修(Issue)、里程碑、通知提醒、标签归档等多样化任务管理工具,支持各类开发任务的发布、指派与跟踪,同时提供在线Wiki文档、组织多粒度管理等功能,为您搭建一站式的项目过程管理环境,让您的团队协作更高效、过程更透明!
|
||||||
|
|
||||||
- **高效流水线运维**:融合DevOps思想,提供轻量级的工作流引擎(Engine),打通编码、测试、构建、部署等开发运维环节;支持自定义配置、代码静态扫描、构建自动触发、容器镜像托管等功能,同时支持接入第三方运维工具,让您的代码更加快速、可靠地形成高质量的产品!
|
- **高效流水线运维**:融合DevOps思想,提供轻量级的工作流引擎(Engine),打通编码、测试、构建、部署等开发运维环节;支持自定义配置、代码静态扫描、构建自动触发、容器镜像托管等功能,同时支持接入第三方运维工具,让您的代码更加快速、可靠地形成高质量的产品!
|
||||||
|
|
||||||
|
@ -35,52 +34,18 @@ GitLink(确实开源)是中国计算机学会(CCF)官方指定的开源
|
||||||
* imagemagick
|
* imagemagick
|
||||||
|
|
||||||
### 步骤
|
### 步骤
|
||||||
(1)安装 Rails 必要的一些三方库:
|
|
||||||
- Mac OS X
|
(1)克隆稳定版本
|
||||||
```bash
|
|
||||||
brew install imagemagick ghostscript libxml2 libxslt libiconv
|
|
||||||
```
|
```
|
||||||
|
|
||||||
- Ubuntu
|
|
||||||
```bash
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get install -y openssl libssl-dev imagemagick git ruby-dev nodejs libmariadb-dev libmysqlclient-dev shared-mime-info libpq-dev libxml2-dev libxslt-dev
|
|
||||||
sudo DEBIAN_FRONTEND="noninteractive" apt-get install -y tzdata
|
|
||||||
sudo ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
|
|
||||||
```
|
|
||||||
|
|
||||||
(2)安装 Ruby, Rails 运行环境:[如何快速正确的安装 Ruby, Rails 运行环境](https://ruby-china.org/wiki/install_ruby_guide)
|
|
||||||
```bash
|
|
||||||
#检验环境是否正确
|
|
||||||
ruby -v
|
|
||||||
#ruby 2.4.x ...
|
|
||||||
|
|
||||||
gem -v
|
|
||||||
#3.x.x
|
|
||||||
|
|
||||||
bundle -v
|
|
||||||
#Bundler version 2.x.x
|
|
||||||
|
|
||||||
rails -v
|
|
||||||
#Rails 5.2.x
|
|
||||||
```
|
|
||||||
|
|
||||||
(3)克隆稳定版本
|
|
||||||
```bash
|
|
||||||
git clone -b master https://gitlink.org.cn/Gitlink/forgeplus.git
|
git clone -b master https://gitlink.org.cn/Gitlink/forgeplus.git
|
||||||
```
|
```
|
||||||
|
|
||||||
(4)安装依赖包
|
(2)安装依赖包
|
||||||
```bash
|
```bash
|
||||||
#进入目录
|
cd forgeplus && bundle install
|
||||||
cd forgeplus
|
|
||||||
#删除Gemfile.lock
|
|
||||||
rm -rf Gemfile.lock
|
|
||||||
#安装依赖包
|
|
||||||
bundle install
|
|
||||||
```
|
```
|
||||||
|
|
||||||
(5)配置初始化文件:进入项目根目录执行以下命令
|
(3)配置初始化文件:进入项目根目录执行以下命令
|
||||||
```bash
|
```bash
|
||||||
cp config/configuration.yml.example config/configuration.yml
|
cp config/configuration.yml.example config/configuration.yml
|
||||||
cp config/database.yml.example config/database.yml
|
cp config/database.yml.example config/database.yml
|
||||||
|
@ -88,8 +53,8 @@ touch config/redis.yml
|
||||||
touch config/elasticsearch.yml
|
touch config/elasticsearch.yml
|
||||||
```
|
```
|
||||||
|
|
||||||
(6)配置数据库:数据库配置信息请查看/config/database.yml文件,项目默认采用mysql数据库, 如需更改,请自行修改配置信息,默认配置如下
|
(4)配置数据库:数据库配置信息请查看/config/database.yml文件,项目默认采用mysql数据库, 如需更改,请自行修改配置信息,默认配置如下
|
||||||
```yaml
|
```bash
|
||||||
default: &default
|
default: &default
|
||||||
adapter: mysql2
|
adapter: mysql2
|
||||||
host: 127.0.0.1
|
host: 127.0.0.1
|
||||||
|
@ -98,7 +63,7 @@ default: &default
|
||||||
password: 123456
|
password: 123456
|
||||||
```
|
```
|
||||||
|
|
||||||
(7)配置gitea服务(可选):如需要部署自己的gitea平台,请参考[gitea官方平台文档](https://docs.gitea.io/zh-cn/install-from-binary/)。因目前gitea平台api受限,暂时推荐从forge平台获取[gitea部署文件](https://www.gitlink.org.cn/Gitlink/gitea-binary)进行部署
|
(5)配置gitea服务(可选):如需要部署自己的gitea平台,请参考[gitea官方平台文档](https://docs.gitea.io/zh-cn/install-from-binary/)。因目前gitea平台api受限,暂时推荐从forge平台获取[gitea部署文件](https://www.gitlink.org.cn/Gitlink/gitea-binary)进行部署
|
||||||
|
|
||||||
- 配置gitea服务步骤:
|
- 配置gitea服务步骤:
|
||||||
|
|
||||||
|
@ -106,68 +71,69 @@ default: &default
|
||||||
|
|
||||||
-- 修改forge平台的 config/configuration.yml中的gitea服务指向地址,如:
|
-- 修改forge平台的 config/configuration.yml中的gitea服务指向地址,如:
|
||||||
|
|
||||||
```yaml
|
```ruby
|
||||||
gitea:
|
gitea:
|
||||||
access_key_id: 'root'
|
access_key_id: 'root'
|
||||||
access_key_secret: 'password'
|
access_key_secret: 'password'
|
||||||
domain: 'http://www.gitea.example.com'
|
domain: 'http://www.gitea.example.com'
|
||||||
base_url: '/api/v1'
|
base_url: '/api/v1'
|
||||||
hat_base_url: '/api/hat'
|
|
||||||
```
|
```
|
||||||
|
|
||||||
(8)配置/config/database.yml文件(安装redis环境:请自行搜索各平台如何安装部署redis环境)
|
(6)安装redis环境:请自行搜索各平台如何安装部署redis环境
|
||||||
```yaml
|
|
||||||
default: &default
|
|
||||||
url: redis://localhost:6379
|
|
||||||
db: 1
|
|
||||||
|
|
||||||
production:
|
(7)安装imagemagick插件:
|
||||||
<<: *default
|
- Mac OS X
|
||||||
url: redis://localhost:6379
|
```bash
|
||||||
|
brew install imagemagick ghostscript
|
||||||
```
|
```
|
||||||
|
|
||||||
(9)创建数据库:开发环境为development, 生成环境为production
|
- Linux
|
||||||
|
```bash
|
||||||
|
sudo apt-get install -y imagemagick
|
||||||
|
```
|
||||||
|
|
||||||
|
(8)创建数据库:开发环境为development, 生成环境为production
|
||||||
```bash
|
```bash
|
||||||
rails db:create RAILS_ENV=development
|
rails db:create RAILS_ENV=development
|
||||||
```
|
```
|
||||||
|
|
||||||
(10)导入数据表结构
|
(9)导入数据表结构
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
bundle exec rake sync_table_structure:import_csv
|
bundle exec rake sync_table_structure:import_csv
|
||||||
```
|
```
|
||||||
|
|
||||||
(11)执行migrate迁移文件:开发环境为development, 生成环境为production
|
(10)执行migrate迁移文件:开发环境为development, 生成环境为production
|
||||||
```bash
|
```bash
|
||||||
rails db:migrate RAILS_ENV=development
|
rails db:migrate RAILS_ENV=development
|
||||||
```
|
```
|
||||||
|
|
||||||
(12)clone前端代码:将前端代码克隆到public/react目录下,目录结构应该是: public/react/build
|
(11)clone前端代码:将前端代码克隆到public/react目录下,目录结构应该是: public/react/build
|
||||||
```bash
|
```bash
|
||||||
git clone -b master https://gitlink.org.cn/Gitlink/build.git
|
git clone -b standalone https://gitlink.org.cn/Gitlink/build.git
|
||||||
```
|
```
|
||||||
|
|
||||||
(13)启动redis(此处以macOS系统为例)
|
(12)启动redis(此处以macOS系统为例)
|
||||||
```bash
|
```bash
|
||||||
redis-server&
|
redis-server&
|
||||||
```
|
```
|
||||||
|
|
||||||
(14)启动sidekiq:开发环境为development, 生成环境为production
|
(13)启动sidekiq:开发环境为development, 生成环境为production
|
||||||
```bash
|
```bash
|
||||||
bundle exec sidekiq -C config/sidekiq.yml -e production -d
|
bundle exec sidekiq -C config/sidekiq.yml -e production -d
|
||||||
```
|
```
|
||||||
|
|
||||||
(15)启动rails服务
|
(14)启动rails服务
|
||||||
```bash
|
```bash
|
||||||
rails s
|
rails s
|
||||||
```
|
```
|
||||||
|
|
||||||
(16)浏览器访问:在浏览器中输入如下地址访问
|
(15)浏览器访问:在浏览器中输入如下地址访问
|
||||||
```bash
|
```bash
|
||||||
http://localhost:3000/
|
http://localhost:3000/
|
||||||
```
|
```
|
||||||
|
|
||||||
(17)其他说明:通过页面注册以第一个用户为平台管理员用户
|
(16)其他说明:通过页面注册以第一个用户为平台管理员用户
|
||||||
|
|
||||||
|
|
||||||
## 页面展示
|
## 页面展示
|
||||||
|
@ -175,31 +141,31 @@ http://localhost:3000/
|
||||||
- 项目列表
|
- 项目列表
|
||||||
|
|
||||||
<center>
|
<center>
|
||||||
<img src="docs/figs/project_list.png" width=80% />
|
<img src="https://code.gitlink.org.cn/young/forgeplus/raw/branch/master/docs/figs/project_list.png?raw=true" width=50% />
|
||||||
</center>
|
</center>
|
||||||
|
|
||||||
- 代码仓库
|
- 代码仓库
|
||||||
|
|
||||||
<center>
|
<center>
|
||||||
<img src="docs/figs/repo.png" width=80% />
|
<img src="https://code.gitlink.org.cn/young/forgeplus/raw/branch/master/docs/figs/repo.png?raw=true" width=50% />
|
||||||
</center>
|
</center>
|
||||||
|
|
||||||
- 任务管理
|
- 任务管理
|
||||||
|
|
||||||
<center>
|
<center>
|
||||||
<img src="docs/figs/issues.png" width=80% />
|
<img src="https://code.gitlink.org.cn/young/forgeplus/raw/branch/master/docs/figs/issues.png?raw=true" width=50% />
|
||||||
</center>
|
</center>
|
||||||
|
|
||||||
- 合并请求
|
- 合并请求
|
||||||
|
|
||||||
<center>
|
<center>
|
||||||
<img src="docs/figs/PR.png" width=80% />
|
<img src="https://code.gitlink.org.cn/young/forgeplus/raw/branch/master/docs/figs/PR.png?raw=true" width=50% />
|
||||||
</center>
|
</center>
|
||||||
|
|
||||||
- 引擎配置
|
- 引擎配置
|
||||||
|
|
||||||
<center>
|
<center>
|
||||||
<img src="docs/figs/engine.png" width=80% />
|
<img src="https://code.gitlink.org.cn/young/forgeplus/raw/branch/master/docs/figs/engine.png?raw=true" width=50% />
|
||||||
</center>
|
</center>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,137 +1,136 @@
|
||||||
//= require rails-ujs
|
//= require rails-ujs
|
||||||
//= require activestorage
|
//= require activestorage
|
||||||
//= require turbolinks
|
//= require turbolinks
|
||||||
//= require jquery3
|
//= require jquery3
|
||||||
//= require popper
|
//= require popper
|
||||||
//= require bootstrap-sprockets
|
//= require bootstrap-sprockets
|
||||||
//= require jquery.validate.min
|
//= require jquery.validate.min
|
||||||
//= require additional-methods.min
|
//= require additional-methods.min
|
||||||
//= require bootstrap-notify
|
//= require bootstrap-notify
|
||||||
//= require jquery.cookie.min
|
//= require jquery.cookie.min
|
||||||
//= require select2
|
//= require select2
|
||||||
//= require moment.min
|
//= require moment.min
|
||||||
//= require jquery.cxselect
|
//= require jquery.cxselect
|
||||||
//= require bootstrap-datepicker
|
//= require bootstrap-datepicker
|
||||||
//= require bootstrap-datetimepicker
|
//= require bootstrap-datetimepicker
|
||||||
//= require bootstrap.viewer
|
//= require bootstrap.viewer
|
||||||
//= require bootstrap/bootstrap-toggle
|
//= require jquery.mloading
|
||||||
//= require jquery.mloading
|
//= require jquery-confirm.min
|
||||||
//= require jquery-confirm.min
|
//= require common
|
||||||
//= require common
|
|
||||||
|
//= require echarts
|
||||||
//= require echarts
|
//= require codemirror/lib/codemirror
|
||||||
//= require codemirror/lib/codemirror
|
//= require codemirror/mode/shell/shell
|
||||||
//= require codemirror/mode/shell/shell
|
//= require editormd/editormd
|
||||||
//= require editormd/editormd
|
//= require editormd/languages/zh-tw
|
||||||
//= require editormd/languages/zh-tw
|
//= require dragula/dragula
|
||||||
//= require dragula/dragula
|
|
||||||
|
//= require_tree ./i18n
|
||||||
//= require_tree ./i18n
|
//= require_tree ./admins
|
||||||
//= require_tree ./admins
|
|
||||||
|
|
||||||
|
$.ajaxSetup({
|
||||||
$.ajaxSetup({
|
beforeSend: function(xhr) {
|
||||||
beforeSend: function(xhr) {
|
xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'));
|
||||||
xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'));
|
}
|
||||||
}
|
});
|
||||||
});
|
|
||||||
|
// ******** select2 global config ********
|
||||||
// ******** select2 global config ********
|
$.fn.select2.defaults.set('theme', 'bootstrap4');
|
||||||
$.fn.select2.defaults.set('theme', 'bootstrap4');
|
$.fn.select2.defaults.set('language', 'zh-CN');
|
||||||
$.fn.select2.defaults.set('language', 'zh-CN');
|
|
||||||
|
Turbolinks.setProgressBarDelay(200);
|
||||||
Turbolinks.setProgressBarDelay(200);
|
|
||||||
|
$.notifyDefaults({
|
||||||
$.notifyDefaults({
|
type: 'success',
|
||||||
type: 'success',
|
z_index: 9999,
|
||||||
z_index: 9999,
|
delay: 2000
|
||||||
delay: 2000
|
});
|
||||||
});
|
|
||||||
|
function show_success_flash(){
|
||||||
function show_success_flash(){
|
$.notify({
|
||||||
$.notify({
|
message: '操作成功'
|
||||||
message: '操作成功'
|
},{
|
||||||
},{
|
type: 'success'
|
||||||
type: 'success'
|
});
|
||||||
});
|
}
|
||||||
}
|
|
||||||
|
$(document).on('turbolinks:load', function(){
|
||||||
$(document).on('turbolinks:load', function(){
|
$('[data-toggle="tooltip"]').tooltip({ trigger : 'hover' });
|
||||||
$('[data-toggle="tooltip"]').tooltip({ trigger : 'hover' });
|
$('[data-toggle="popover"]').popover();
|
||||||
$('[data-toggle="popover"]').popover();
|
|
||||||
|
// 图片查看大图
|
||||||
// 图片查看大图
|
$('img.preview-image').bootstrapViewer();
|
||||||
$('img.preview-image').bootstrapViewer();
|
|
||||||
|
// flash alert提示框自动关闭
|
||||||
// flash alert提示框自动关闭
|
if($('.admin-alert-container .alert').length > 0){
|
||||||
if($('.admin-alert-container .alert').length > 0){
|
setTimeout(function(){
|
||||||
setTimeout(function(){
|
$('.admin-alert-container .alert:not(.alert-danger)').alert('close');
|
||||||
$('.admin-alert-container .alert:not(.alert-danger)').alert('close');
|
}, 2000);
|
||||||
}, 2000);
|
setTimeout(function(){
|
||||||
setTimeout(function(){
|
$('.admin-alert-container .alert.alert-danger').alert('close');
|
||||||
$('.admin-alert-container .alert.alert-danger').alert('close');
|
}, 5000);
|
||||||
}, 5000);
|
}
|
||||||
}
|
});
|
||||||
});
|
|
||||||
|
$(document).on("turbolinks:before-cache", function () {
|
||||||
$(document).on("turbolinks:before-cache", function () {
|
$('[data-toggle="tooltip"]').tooltip('hide');
|
||||||
$('[data-toggle="tooltip"]').tooltip('hide');
|
$('[data-toggle="popover"]').popover('hide');
|
||||||
$('[data-toggle="popover"]').popover('hide');
|
});
|
||||||
});
|
// var progressBar = new Turbolinks.ProgressBar();
|
||||||
// var progressBar = new Turbolinks.ProgressBar();
|
|
||||||
|
// $(document).on('ajax:send', function(event){
|
||||||
// $(document).on('ajax:send', function(event){
|
// console.log('ajax send', event);
|
||||||
// console.log('ajax send', event);
|
// progressBar.setValue(0)
|
||||||
// progressBar.setValue(0)
|
// progressBar.show()
|
||||||
// progressBar.show()
|
// });
|
||||||
// });
|
//
|
||||||
//
|
// $(document).on('ajax:complete', function(event){
|
||||||
// $(document).on('ajax:complete', function(event){
|
// console.log('ajax complete', event);
|
||||||
// console.log('ajax complete', event);
|
// progressBar.setValue(1)
|
||||||
// progressBar.setValue(1)
|
// progressBar.hide() // 分页时不触发,奇怪
|
||||||
// progressBar.hide() // 分页时不触发,奇怪
|
// });
|
||||||
// });
|
// $(document).on('ajax:success', function(event){
|
||||||
// $(document).on('ajax:success', function(event){
|
// console.log('ajax success', event);
|
||||||
// console.log('ajax success', event);
|
// });
|
||||||
// });
|
// $(document).on('ajax:error', function(event){
|
||||||
// $(document).on('ajax:error', function(event){
|
// console.log('ajax error', event);
|
||||||
// console.log('ajax error', event);
|
// });
|
||||||
// });
|
|
||||||
|
$(function () {
|
||||||
$(function () {
|
});
|
||||||
});
|
|
||||||
|
$(document).on('turbolinks:load', function() {
|
||||||
$(document).on('turbolinks:load', function() {
|
|
||||||
|
$('.logo-item-left').on("change", 'input[type="file"]', function () {
|
||||||
$('.logo-item-left').on("change", 'input[type="file"]', function () {
|
var $fileInput = $(this);
|
||||||
var $fileInput = $(this);
|
var file = this.files[0];
|
||||||
var file = this.files[0];
|
var imageType = /image.*/;
|
||||||
var imageType = /image.*/;
|
if (file && file.type.match(imageType)) {
|
||||||
if (file && file.type.match(imageType)) {
|
var reader = new FileReader();
|
||||||
var reader = new FileReader();
|
reader.onload = function () {
|
||||||
reader.onload = function () {
|
var $box = $fileInput.parent();
|
||||||
var $box = $fileInput.parent();
|
$box.find('img').attr('src', reader.result).css('display', 'block');
|
||||||
$box.find('img').attr('src', reader.result).css('display', 'block');
|
$box.addClass('has-img');
|
||||||
$box.addClass('has-img');
|
};
|
||||||
};
|
reader.readAsDataURL(file);
|
||||||
reader.readAsDataURL(file);
|
} else {
|
||||||
} else {
|
}
|
||||||
}
|
});
|
||||||
});
|
|
||||||
|
$('.attachment-item-left').on("change", 'input[type="file"]', function () {
|
||||||
$('.attachment-item-left').on("change", 'input[type="file"]', function () {
|
var $fileInput = $(this);
|
||||||
var $fileInput = $(this);
|
var file = this.files[0];
|
||||||
var file = this.files[0];
|
var imageType = /image.*/;
|
||||||
var imageType = /image.*/;
|
if (file && file.type.match(imageType)) {
|
||||||
if (file && file.type.match(imageType)) {
|
var reader = new FileReader();
|
||||||
var reader = new FileReader();
|
reader.onload = function () {
|
||||||
reader.onload = function () {
|
var $box = $fileInput.parent();
|
||||||
var $box = $fileInput.parent();
|
$box.find('img').attr('src', reader.result).css('display', 'block');
|
||||||
$box.find('img').attr('src', reader.result).css('display', 'block');
|
$box.addClass('has-img');
|
||||||
$box.addClass('has-img');
|
};
|
||||||
};
|
reader.readAsDataURL(file);
|
||||||
reader.readAsDataURL(file);
|
} else {
|
||||||
} else {
|
}
|
||||||
}
|
});
|
||||||
});
|
|
||||||
})
|
})
|
|
@ -1,2 +0,0 @@
|
||||||
// Place all the behaviors and hooks related to the matching controller here.
|
|
||||||
// All this logic will automatically be available in application.js.
|
|
|
@ -1,2 +0,0 @@
|
||||||
// Place all the behaviors and hooks related to the matching controller here.
|
|
||||||
// All this logic will automatically be available in application.js.
|
|
|
@ -63,7 +63,7 @@ $(document).on('turbolinks:load', function() {
|
||||||
|
|
||||||
if(!valid) return;
|
if(!valid) return;
|
||||||
$.ajax({
|
$.ajax({
|
||||||
method: 'PUT',
|
method: 'PATCH',
|
||||||
dataType: 'json',
|
dataType: 'json',
|
||||||
url: $form.attr('action'),
|
url: $form.attr('action'),
|
||||||
data: new FormData($form[0]),
|
data: new FormData($form[0]),
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
// Place all the behaviors and hooks related to the matching controller here.
|
|
||||||
// All this logic will automatically be available in application.js.
|
|
|
@ -1,65 +0,0 @@
|
||||||
$(document).on('turbolinks:load', function(){
|
|
||||||
if ($('body.admins-organizations-index-page').length > 0) {
|
|
||||||
var showSuccessNotify = function() {
|
|
||||||
$.notify({
|
|
||||||
message: '操作成功'
|
|
||||||
},{
|
|
||||||
type: 'success'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// organizations open cla
|
|
||||||
$('.organizations-list-container').on('click', '.open-cla-action', function(){
|
|
||||||
var $openClaAction = $(this);
|
|
||||||
var $closeClaAction = $openClaAction.siblings('.close-cla-action');
|
|
||||||
|
|
||||||
var userId = $openClaAction.data('id');
|
|
||||||
customConfirm({
|
|
||||||
content: '确认开通吗?',
|
|
||||||
ok: function () {
|
|
||||||
$.ajax({
|
|
||||||
url: '/admins/organizations/' + userId + '/open_cla',
|
|
||||||
method: 'POST',
|
|
||||||
dataType: 'json',
|
|
||||||
success: function() {
|
|
||||||
showSuccessNotify();
|
|
||||||
$closeClaAction.show();
|
|
||||||
$openClaAction.hide();
|
|
||||||
},
|
|
||||||
error: function(res){
|
|
||||||
$.notify({ message: res.responseJSON.message }, { type: 'danger' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
// organizations close cla
|
|
||||||
$('.organizations-list-container').on('click', '.close-cla-action', function(){
|
|
||||||
var $closeClaAction = $(this);
|
|
||||||
var $openClaAction= $closeClaAction.siblings('.open-cla-action');
|
|
||||||
|
|
||||||
var userId = $openClaAction.data('id');
|
|
||||||
customConfirm({
|
|
||||||
content: '确认关闭吗?',
|
|
||||||
ok: function () {
|
|
||||||
$.ajax({
|
|
||||||
url: '/admins/organizations/' + userId + '/close_cla',
|
|
||||||
method: 'POST',
|
|
||||||
dataType: 'json',
|
|
||||||
success: function() {
|
|
||||||
showSuccessNotify();
|
|
||||||
$openClaAction.show();
|
|
||||||
$closeClaAction.hide();
|
|
||||||
},
|
|
||||||
error: function(res){
|
|
||||||
$.notify({ message: res.responseJSON.message }, { type: 'danger' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,3 +0,0 @@
|
||||||
// Place all the behaviors and hooks related to the matching controller here.
|
|
||||||
// All this logic will automatically be available in application.js.
|
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
// Place all the behaviors and hooks related to the matching controller here.
|
|
||||||
// All this logic will automatically be available in application.js.
|
|
|
@ -94,20 +94,6 @@ $(document).on('turbolinks:load', function(){
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
// reset user login times
|
|
||||||
$('.users-list-container').on('click', '.fresh-gitea-token-action', function(){
|
|
||||||
var $action = $(this);
|
|
||||||
|
|
||||||
var userId = $action.data('id');
|
|
||||||
$.ajax({
|
|
||||||
url: '/admins/users/' + userId + '/fresh_gitea_token',
|
|
||||||
method: 'POST',
|
|
||||||
dataType: 'json',
|
|
||||||
success: function() {
|
|
||||||
showSuccessNotify();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// ***************** reward grade modal *****************
|
// ***************** reward grade modal *****************
|
||||||
var $rewardGradeModal = $('.admin-users-reward-grade-modal');
|
var $rewardGradeModal = $('.admin-users-reward-grade-modal');
|
||||||
|
|
|
@ -1,180 +0,0 @@
|
||||||
/*! ========================================================================
|
|
||||||
* Bootstrap Toggle: bootstrap-toggle.js v2.2.0
|
|
||||||
* http://www.bootstraptoggle.com
|
|
||||||
* ========================================================================
|
|
||||||
* Copyright 2014 Min Hur, The New York Times Company
|
|
||||||
* Licensed under MIT
|
|
||||||
* ======================================================================== */
|
|
||||||
|
|
||||||
|
|
||||||
+function ($) {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
// TOGGLE PUBLIC CLASS DEFINITION
|
|
||||||
// ==============================
|
|
||||||
|
|
||||||
var Toggle = function (element, options) {
|
|
||||||
this.$element = $(element)
|
|
||||||
this.options = $.extend({}, this.defaults(), options)
|
|
||||||
this.render()
|
|
||||||
}
|
|
||||||
|
|
||||||
Toggle.VERSION = '2.2.0'
|
|
||||||
|
|
||||||
Toggle.DEFAULTS = {
|
|
||||||
on: 'On',
|
|
||||||
off: 'Off',
|
|
||||||
onstyle: 'primary',
|
|
||||||
offstyle: 'default',
|
|
||||||
size: 'normal',
|
|
||||||
style: '',
|
|
||||||
width: null,
|
|
||||||
height: null
|
|
||||||
}
|
|
||||||
|
|
||||||
Toggle.prototype.defaults = function() {
|
|
||||||
return {
|
|
||||||
on: this.$element.attr('data-on') || Toggle.DEFAULTS.on,
|
|
||||||
off: this.$element.attr('data-off') || Toggle.DEFAULTS.off,
|
|
||||||
onstyle: this.$element.attr('data-onstyle') || Toggle.DEFAULTS.onstyle,
|
|
||||||
offstyle: this.$element.attr('data-offstyle') || Toggle.DEFAULTS.offstyle,
|
|
||||||
size: this.$element.attr('data-size') || Toggle.DEFAULTS.size,
|
|
||||||
style: this.$element.attr('data-style') || Toggle.DEFAULTS.style,
|
|
||||||
width: this.$element.attr('data-width') || Toggle.DEFAULTS.width,
|
|
||||||
height: this.$element.attr('data-height') || Toggle.DEFAULTS.height
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Toggle.prototype.render = function () {
|
|
||||||
this._onstyle = 'btn-' + this.options.onstyle
|
|
||||||
this._offstyle = 'btn-' + this.options.offstyle
|
|
||||||
var size = this.options.size === 'large' ? 'btn-lg'
|
|
||||||
: this.options.size === 'small' ? 'btn-sm'
|
|
||||||
: this.options.size === 'mini' ? 'btn-xs'
|
|
||||||
: ''
|
|
||||||
var $toggleOn = $('<label class="btn">').html(this.options.on)
|
|
||||||
.addClass(this._onstyle + ' ' + size)
|
|
||||||
var $toggleOff = $('<label class="btn">').html(this.options.off)
|
|
||||||
.addClass(this._offstyle + ' ' + size + ' active')
|
|
||||||
var $toggleHandle = $('<span class="toggle-handle btn btn-default">')
|
|
||||||
.addClass(size)
|
|
||||||
var $toggleGroup = $('<div class="toggle-group">')
|
|
||||||
.append($toggleOn, $toggleOff, $toggleHandle)
|
|
||||||
var $toggle = $('<div class="toggle btn" data-toggle="toggle">')
|
|
||||||
.addClass( this.$element.prop('checked') ? this._onstyle : this._offstyle+' off' )
|
|
||||||
.addClass(size).addClass(this.options.style)
|
|
||||||
|
|
||||||
this.$element.wrap($toggle)
|
|
||||||
$.extend(this, {
|
|
||||||
$toggle: this.$element.parent(),
|
|
||||||
$toggleOn: $toggleOn,
|
|
||||||
$toggleOff: $toggleOff,
|
|
||||||
$toggleGroup: $toggleGroup
|
|
||||||
})
|
|
||||||
this.$toggle.append($toggleGroup)
|
|
||||||
|
|
||||||
var width = this.options.width || Math.max($toggleOn.outerWidth(), $toggleOff.outerWidth())+($toggleHandle.outerWidth()/2)
|
|
||||||
var height = this.options.height || Math.max($toggleOn.outerHeight(), $toggleOff.outerHeight())
|
|
||||||
$toggleOn.addClass('toggle-on')
|
|
||||||
$toggleOff.addClass('toggle-off')
|
|
||||||
this.$toggle.css({ width: width, height: height })
|
|
||||||
if (this.options.height) {
|
|
||||||
$toggleOn.css('line-height', $toggleOn.height() + 'px')
|
|
||||||
$toggleOff.css('line-height', $toggleOff.height() + 'px')
|
|
||||||
}
|
|
||||||
this.update(true)
|
|
||||||
this.trigger(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
Toggle.prototype.toggle = function () {
|
|
||||||
if (this.$element.prop('checked')) this.off()
|
|
||||||
else this.on()
|
|
||||||
}
|
|
||||||
|
|
||||||
Toggle.prototype.on = function (silent) {
|
|
||||||
if (this.$element.prop('disabled')) return false
|
|
||||||
this.$toggle.removeClass(this._offstyle + ' off').addClass(this._onstyle)
|
|
||||||
this.$element.prop('checked', true)
|
|
||||||
if (!silent) this.trigger()
|
|
||||||
}
|
|
||||||
|
|
||||||
Toggle.prototype.off = function (silent) {
|
|
||||||
if (this.$element.prop('disabled')) return false
|
|
||||||
this.$toggle.removeClass(this._onstyle).addClass(this._offstyle + ' off')
|
|
||||||
this.$element.prop('checked', false)
|
|
||||||
if (!silent) this.trigger()
|
|
||||||
}
|
|
||||||
|
|
||||||
Toggle.prototype.enable = function () {
|
|
||||||
this.$toggle.removeAttr('disabled')
|
|
||||||
this.$element.prop('disabled', false)
|
|
||||||
}
|
|
||||||
|
|
||||||
Toggle.prototype.disable = function () {
|
|
||||||
this.$toggle.attr('disabled', 'disabled')
|
|
||||||
this.$element.prop('disabled', true)
|
|
||||||
}
|
|
||||||
|
|
||||||
Toggle.prototype.update = function (silent) {
|
|
||||||
if (this.$element.prop('disabled')) this.disable()
|
|
||||||
else this.enable()
|
|
||||||
if (this.$element.prop('checked')) this.on(silent)
|
|
||||||
else this.off(silent)
|
|
||||||
}
|
|
||||||
|
|
||||||
Toggle.prototype.trigger = function (silent) {
|
|
||||||
this.$element.off('change.bs.toggle')
|
|
||||||
if (!silent) this.$element.change()
|
|
||||||
this.$element.on('change.bs.toggle', $.proxy(function() {
|
|
||||||
this.update()
|
|
||||||
}, this))
|
|
||||||
}
|
|
||||||
|
|
||||||
Toggle.prototype.destroy = function() {
|
|
||||||
this.$element.off('change.bs.toggle')
|
|
||||||
this.$toggleGroup.remove()
|
|
||||||
this.$element.removeData('bs.toggle')
|
|
||||||
this.$element.unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
// TOGGLE PLUGIN DEFINITION
|
|
||||||
// ========================
|
|
||||||
|
|
||||||
function Plugin(option) {
|
|
||||||
return this.each(function () {
|
|
||||||
var $this = $(this)
|
|
||||||
var data = $this.data('bs.toggle')
|
|
||||||
var options = typeof option == 'object' && option
|
|
||||||
|
|
||||||
if (!data) $this.data('bs.toggle', (data = new Toggle(this, options)))
|
|
||||||
if (typeof option == 'string' && data[option]) data[option]()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
var old = $.fn.bootstrapToggle
|
|
||||||
|
|
||||||
$.fn.bootstrapToggle = Plugin
|
|
||||||
$.fn.bootstrapToggle.Constructor = Toggle
|
|
||||||
|
|
||||||
// TOGGLE NO CONFLICT
|
|
||||||
// ==================
|
|
||||||
|
|
||||||
$.fn.toggle.noConflict = function () {
|
|
||||||
$.fn.bootstrapToggle = old
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
// TOGGLE DATA-API
|
|
||||||
// ===============
|
|
||||||
|
|
||||||
$(function() {
|
|
||||||
$('input[type=checkbox][data-toggle^=toggle]').bootstrapToggle()
|
|
||||||
})
|
|
||||||
|
|
||||||
$(document).on('click.bs.toggle', 'div[data-toggle^=toggle]', function(e) {
|
|
||||||
var $checkbox = $(this).find('input[type=checkbox]')
|
|
||||||
$checkbox.bootstrapToggle('toggle')
|
|
||||||
e.preventDefault()
|
|
||||||
})
|
|
||||||
|
|
||||||
}(jQuery);
|
|
|
@ -1,9 +0,0 @@
|
||||||
/*! ========================================================================
|
|
||||||
* Bootstrap Toggle: bootstrap-toggle.js v2.2.0
|
|
||||||
* http://www.bootstraptoggle.com
|
|
||||||
* ========================================================================
|
|
||||||
* Copyright 2014 Min Hur, The New York Times Company
|
|
||||||
* Licensed under MIT
|
|
||||||
* ======================================================================== */
|
|
||||||
+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.toggle"),f="object"==typeof b&&b;e||d.data("bs.toggle",e=new c(this,f)),"string"==typeof b&&e[b]&&e[b]()})}var c=function(b,c){this.$element=a(b),this.options=a.extend({},this.defaults(),c),this.render()};c.VERSION="2.2.0",c.DEFAULTS={on:"On",off:"Off",onstyle:"primary",offstyle:"default",size:"normal",style:"",width:null,height:null},c.prototype.defaults=function(){return{on:this.$element.attr("data-on")||c.DEFAULTS.on,off:this.$element.attr("data-off")||c.DEFAULTS.off,onstyle:this.$element.attr("data-onstyle")||c.DEFAULTS.onstyle,offstyle:this.$element.attr("data-offstyle")||c.DEFAULTS.offstyle,size:this.$element.attr("data-size")||c.DEFAULTS.size,style:this.$element.attr("data-style")||c.DEFAULTS.style,width:this.$element.attr("data-width")||c.DEFAULTS.width,height:this.$element.attr("data-height")||c.DEFAULTS.height}},c.prototype.render=function(){this._onstyle="btn-"+this.options.onstyle,this._offstyle="btn-"+this.options.offstyle;var b="large"===this.options.size?"btn-lg":"small"===this.options.size?"btn-sm":"mini"===this.options.size?"btn-xs":"",c=a('<label class="btn">').html(this.options.on).addClass(this._onstyle+" "+b),d=a('<label class="btn">').html(this.options.off).addClass(this._offstyle+" "+b+" active"),e=a('<span class="toggle-handle btn btn-default">').addClass(b),f=a('<div class="toggle-group">').append(c,d,e),g=a('<div class="toggle btn" data-toggle="toggle">').addClass(this.$element.prop("checked")?this._onstyle:this._offstyle+" off").addClass(b).addClass(this.options.style);this.$element.wrap(g),a.extend(this,{$toggle:this.$element.parent(),$toggleOn:c,$toggleOff:d,$toggleGroup:f}),this.$toggle.append(f);var h=this.options.width||Math.max(c.outerWidth(),d.outerWidth())+e.outerWidth()/2,i=this.options.height||Math.max(c.outerHeight(),d.outerHeight());c.addClass("toggle-on"),d.addClass("toggle-off"),this.$toggle.css({width:h,height:i}),this.options.height&&(c.css("line-height",c.height()+"px"),d.css("line-height",d.height()+"px")),this.update(!0),this.trigger(!0)},c.prototype.toggle=function(){this.$element.prop("checked")?this.off():this.on()},c.prototype.on=function(a){return this.$element.prop("disabled")?!1:(this.$toggle.removeClass(this._offstyle+" off").addClass(this._onstyle),this.$element.prop("checked",!0),void(a||this.trigger()))},c.prototype.off=function(a){return this.$element.prop("disabled")?!1:(this.$toggle.removeClass(this._onstyle).addClass(this._offstyle+" off"),this.$element.prop("checked",!1),void(a||this.trigger()))},c.prototype.enable=function(){this.$toggle.removeAttr("disabled"),this.$element.prop("disabled",!1)},c.prototype.disable=function(){this.$toggle.attr("disabled","disabled"),this.$element.prop("disabled",!0)},c.prototype.update=function(a){this.$element.prop("disabled")?this.disable():this.enable(),this.$element.prop("checked")?this.on(a):this.off(a)},c.prototype.trigger=function(b){this.$element.off("change.bs.toggle"),b||this.$element.change(),this.$element.on("change.bs.toggle",a.proxy(function(){this.update()},this))},c.prototype.destroy=function(){this.$element.off("change.bs.toggle"),this.$toggleGroup.remove(),this.$element.removeData("bs.toggle"),this.$element.unwrap()};var d=a.fn.bootstrapToggle;a.fn.bootstrapToggle=b,a.fn.bootstrapToggle.Constructor=c,a.fn.toggle.noConflict=function(){return a.fn.bootstrapToggle=d,this},a(function(){a("input[type=checkbox][data-toggle^=toggle]").bootstrapToggle()}),a(document).on("click.bs.toggle","div[data-toggle^=toggle]",function(b){var c=a(this).find("input[type=checkbox]");c.bootstrapToggle("toggle"),b.preventDefault()})}(jQuery);
|
|
||||||
//# sourceMappingURL=bootstrap-toggle.min.js.map
|
|
|
@ -1 +0,0 @@
|
||||||
{"version":3,"file":"bootstrap-toggle.min.js","sources":["bootstrap-toggle.js"],"names":["$","Plugin","option","this","each","$this","data","options","Toggle","element","$element","extend","defaults","render","VERSION","DEFAULTS","on","off","onstyle","offstyle","size","style","width","height","prototype","attr","_onstyle","_offstyle","$toggleOn","html","addClass","$toggleOff","$toggleHandle","$toggleGroup","append","$toggle","prop","wrap","parent","Math","max","outerWidth","outerHeight","css","update","trigger","toggle","silent","removeClass","enable","removeAttr","disable","change","proxy","destroy","remove","removeData","unwrap","old","fn","bootstrapToggle","Constructor","noConflict","document","e","$checkbox","find","preventDefault","jQuery"],"mappings":";;;;;;;CASE,SAAUA,GACV,YAoID,SAASC,GAAOC,GACf,MAAOC,MAAKC,KAAK,WAChB,GAAIC,GAAUL,EAAEG,MACZG,EAAUD,EAAMC,KAAK,aACrBC,EAA2B,gBAAVL,IAAsBA,CAEtCI,IAAMD,EAAMC,KAAK,YAAcA,EAAO,GAAIE,GAAOL,KAAMI,IACvC,gBAAVL,IAAsBI,EAAKJ,IAASI,EAAKJ,OAtItD,GAAIM,GAAS,SAAUC,EAASF,GAC/BJ,KAAKO,SAAYV,EAAES,GACnBN,KAAKI,QAAYP,EAAEW,UAAWR,KAAKS,WAAYL,GAC/CJ,KAAKU,SAGNL,GAAOM,QAAW,QAElBN,EAAOO,UACNC,GAAI,KACJC,IAAK,MACLC,QAAS,UACTC,SAAU,UACVC,KAAM,SACNC,MAAO,GACPC,MAAO,KACPC,OAAQ,MAGTf,EAAOgB,UAAUZ,SAAW,WAC3B,OACCI,GAAIb,KAAKO,SAASe,KAAK,YAAcjB,EAAOO,SAASC,GACrDC,IAAKd,KAAKO,SAASe,KAAK,aAAejB,EAAOO,SAASE,IACvDC,QAASf,KAAKO,SAASe,KAAK,iBAAmBjB,EAAOO,SAASG,QAC/DC,SAAUhB,KAAKO,SAASe,KAAK,kBAAoBjB,EAAOO,SAASI,SACjEC,KAAMjB,KAAKO,SAASe,KAAK,cAAgBjB,EAAOO,SAASK,KACzDC,MAAOlB,KAAKO,SAASe,KAAK,eAAiBjB,EAAOO,SAASM,MAC3DC,MAAOnB,KAAKO,SAASe,KAAK,eAAiBjB,EAAOO,SAASO,MAC3DC,OAAQpB,KAAKO,SAASe,KAAK,gBAAkBjB,EAAOO,SAASQ,SAI/Df,EAAOgB,UAAUX,OAAS,WACzBV,KAAKuB,SAAW,OAASvB,KAAKI,QAAQW,QACtCf,KAAKwB,UAAY,OAASxB,KAAKI,QAAQY,QACvC,IAAIC,GAA6B,UAAtBjB,KAAKI,QAAQa,KAAmB,SAClB,UAAtBjB,KAAKI,QAAQa,KAAmB,SACV,SAAtBjB,KAAKI,QAAQa,KAAkB,SAC/B,GACCQ,EAAY5B,EAAE,uBAAuB6B,KAAK1B,KAAKI,QAAQS,IACzDc,SAAS3B,KAAKuB,SAAW,IAAMN,GAC7BW,EAAa/B,EAAE,uBAAuB6B,KAAK1B,KAAKI,QAAQU,KAC1Da,SAAS3B,KAAKwB,UAAY,IAAMP,EAAO,WACrCY,EAAgBhC,EAAE,gDACpB8B,SAASV,GACPa,EAAejC,EAAE,8BACnBkC,OAAON,EAAWG,EAAYC,GAC5BG,EAAUnC,EAAE,iDACd8B,SAAU3B,KAAKO,SAAS0B,KAAK,WAAajC,KAAKuB,SAAWvB,KAAKwB,UAAU,QACzEG,SAASV,GAAMU,SAAS3B,KAAKI,QAAQc,MAEvClB,MAAKO,SAAS2B,KAAKF,GACnBnC,EAAEW,OAAOR,MACRgC,QAAShC,KAAKO,SAAS4B,SACvBV,UAAWA,EACXG,WAAYA,EACZE,aAAcA,IAEf9B,KAAKgC,QAAQD,OAAOD,EAEpB,IAAIX,GAAQnB,KAAKI,QAAQe,OAASiB,KAAKC,IAAIZ,EAAUa,aAAcV,EAAWU,cAAeT,EAAcS,aAAa,EACpHlB,EAASpB,KAAKI,QAAQgB,QAAUgB,KAAKC,IAAIZ,EAAUc,cAAeX,EAAWW,cACjFd,GAAUE,SAAS,aACnBC,EAAWD,SAAS,cACpB3B,KAAKgC,QAAQQ,KAAMrB,MAAOA,EAAOC,OAAQA,IACrCpB,KAAKI,QAAQgB,SAChBK,EAAUe,IAAI,cAAef,EAAUL,SAAW,MAClDQ,EAAWY,IAAI,cAAeZ,EAAWR,SAAW,OAErDpB,KAAKyC,QAAO,GACZzC,KAAK0C,SAAQ,IAGdrC,EAAOgB,UAAUsB,OAAS,WACrB3C,KAAKO,SAAS0B,KAAK,WAAYjC,KAAKc,MACnCd,KAAKa,MAGXR,EAAOgB,UAAUR,GAAK,SAAU+B,GAC/B,MAAI5C,MAAKO,SAAS0B,KAAK,aAAoB,GAC3CjC,KAAKgC,QAAQa,YAAY7C,KAAKwB,UAAY,QAAQG,SAAS3B,KAAKuB,UAChEvB,KAAKO,SAAS0B,KAAK,WAAW,QACzBW,GAAQ5C,KAAK0C,aAGnBrC,EAAOgB,UAAUP,IAAM,SAAU8B,GAChC,MAAI5C,MAAKO,SAAS0B,KAAK,aAAoB,GAC3CjC,KAAKgC,QAAQa,YAAY7C,KAAKuB,UAAUI,SAAS3B,KAAKwB,UAAY,QAClExB,KAAKO,SAAS0B,KAAK,WAAW,QACzBW,GAAQ5C,KAAK0C,aAGnBrC,EAAOgB,UAAUyB,OAAS,WACzB9C,KAAKgC,QAAQe,WAAW,YACxB/C,KAAKO,SAAS0B,KAAK,YAAY,IAGhC5B,EAAOgB,UAAU2B,QAAU,WAC1BhD,KAAKgC,QAAQV,KAAK,WAAY,YAC9BtB,KAAKO,SAAS0B,KAAK,YAAY,IAGhC5B,EAAOgB,UAAUoB,OAAS,SAAUG,GAC/B5C,KAAKO,SAAS0B,KAAK,YAAajC,KAAKgD,UACpChD,KAAK8C,SACN9C,KAAKO,SAAS0B,KAAK,WAAYjC,KAAKa,GAAG+B,GACtC5C,KAAKc,IAAI8B,IAGfvC,EAAOgB,UAAUqB,QAAU,SAAUE,GACpC5C,KAAKO,SAASO,IAAI,oBACb8B,GAAQ5C,KAAKO,SAAS0C,SAC3BjD,KAAKO,SAASM,GAAG,mBAAoBhB,EAAEqD,MAAM,WAC5ClD,KAAKyC,UACHzC,QAGJK,EAAOgB,UAAU8B,QAAU,WAC1BnD,KAAKO,SAASO,IAAI,oBAClBd,KAAK8B,aAAasB,SAClBpD,KAAKO,SAAS8C,WAAW,aACzBrD,KAAKO,SAAS+C,SAiBf,IAAIC,GAAM1D,EAAE2D,GAAGC,eAEf5D,GAAE2D,GAAGC,gBAA8B3D,EACnCD,EAAE2D,GAAGC,gBAAgBC,YAAcrD,EAKnCR,EAAE2D,GAAGb,OAAOgB,WAAa,WAExB,MADA9D,GAAE2D,GAAGC,gBAAkBF,EAChBvD,MAMRH,EAAE,WACDA,EAAE,6CAA6C4D,oBAGhD5D,EAAE+D,UAAU/C,GAAG,kBAAmB,2BAA4B,SAASgD,GACtE,GAAIC,GAAYjE,EAAEG,MAAM+D,KAAK,uBAC7BD,GAAUL,gBAAgB,UAC1BI,EAAEG,oBAGFC"}
|
|
|
@ -1,180 +0,0 @@
|
||||||
/*! ========================================================================
|
|
||||||
* Bootstrap Toggle: bootstrap2-toggle.js v2.2.0
|
|
||||||
* http://www.bootstraptoggle.com
|
|
||||||
* ========================================================================
|
|
||||||
* Copyright 2014 Min Hur, The New York Times Company
|
|
||||||
* Licensed under MIT
|
|
||||||
* ======================================================================== */
|
|
||||||
|
|
||||||
|
|
||||||
+function ($) {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
// TOGGLE PUBLIC CLASS DEFINITION
|
|
||||||
// ==============================
|
|
||||||
|
|
||||||
var Toggle = function (element, options) {
|
|
||||||
this.$element = $(element)
|
|
||||||
this.options = $.extend({}, this.defaults(), options)
|
|
||||||
this.render()
|
|
||||||
}
|
|
||||||
|
|
||||||
Toggle.VERSION = '2.2.0'
|
|
||||||
|
|
||||||
Toggle.DEFAULTS = {
|
|
||||||
on: 'On',
|
|
||||||
off: 'Off',
|
|
||||||
onstyle: 'primary',
|
|
||||||
offstyle: 'default',
|
|
||||||
size: 'normal',
|
|
||||||
style: '',
|
|
||||||
width: null,
|
|
||||||
height: null
|
|
||||||
}
|
|
||||||
|
|
||||||
Toggle.prototype.defaults = function() {
|
|
||||||
return {
|
|
||||||
on: this.$element.attr('data-on') || Toggle.DEFAULTS.on,
|
|
||||||
off: this.$element.attr('data-off') || Toggle.DEFAULTS.off,
|
|
||||||
onstyle: this.$element.attr('data-onstyle') || Toggle.DEFAULTS.onstyle,
|
|
||||||
offstyle: this.$element.attr('data-offstyle') || Toggle.DEFAULTS.offstyle,
|
|
||||||
size: this.$element.attr('data-size') || Toggle.DEFAULTS.size,
|
|
||||||
style: this.$element.attr('data-style') || Toggle.DEFAULTS.style,
|
|
||||||
width: this.$element.attr('data-width') || Toggle.DEFAULTS.width,
|
|
||||||
height: this.$element.attr('data-height') || Toggle.DEFAULTS.height
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Toggle.prototype.render = function () {
|
|
||||||
this._onstyle = 'btn-' + this.options.onstyle
|
|
||||||
this._offstyle = 'btn-' + this.options.offstyle
|
|
||||||
var size = this.options.size === 'large' ? 'btn-large'
|
|
||||||
: this.options.size === 'small' ? 'btn-small'
|
|
||||||
: this.options.size === 'mini' ? 'btn-mini'
|
|
||||||
: ''
|
|
||||||
var $toggleOn = $('<label class="btn">').html(this.options.on)
|
|
||||||
.addClass(this._onstyle + ' ' + size)
|
|
||||||
var $toggleOff = $('<label class="btn">').html(this.options.off)
|
|
||||||
.addClass(this._offstyle + ' ' + size + ' active')
|
|
||||||
var $toggleHandle = $('<span class="toggle-handle btn btn-default">')
|
|
||||||
.addClass(size)
|
|
||||||
var $toggleGroup = $('<div class="toggle-group">')
|
|
||||||
.append($toggleOn, $toggleOff, $toggleHandle)
|
|
||||||
var $toggle = $('<div class="toggle btn" data-toggle="toggle">')
|
|
||||||
.addClass( this.$element.prop('checked') ? this._onstyle : this._offstyle+' off' )
|
|
||||||
.addClass(size).addClass(this.options.style)
|
|
||||||
|
|
||||||
this.$element.wrap($toggle)
|
|
||||||
$.extend(this, {
|
|
||||||
$toggle: this.$element.parent(),
|
|
||||||
$toggleOn: $toggleOn,
|
|
||||||
$toggleOff: $toggleOff,
|
|
||||||
$toggleGroup: $toggleGroup
|
|
||||||
})
|
|
||||||
this.$toggle.append($toggleGroup)
|
|
||||||
|
|
||||||
var width = this.options.width || Math.max($toggleOn.width(), $toggleOff.width())+($toggleHandle.outerWidth()/2)
|
|
||||||
var height = this.options.height || Math.max($toggleOn.height(), $toggleOff.height())
|
|
||||||
$toggleOn.addClass('toggle-on')
|
|
||||||
$toggleOff.addClass('toggle-off')
|
|
||||||
this.$toggle.css({ width: width, height: height })
|
|
||||||
if (this.options.height) {
|
|
||||||
$toggleOn.css('line-height', $toggleOn.height() + 'px')
|
|
||||||
$toggleOff.css('line-height', $toggleOff.height() + 'px')
|
|
||||||
}
|
|
||||||
this.update(true)
|
|
||||||
this.trigger(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
Toggle.prototype.toggle = function () {
|
|
||||||
if (this.$element.prop('checked')) this.off()
|
|
||||||
else this.on()
|
|
||||||
}
|
|
||||||
|
|
||||||
Toggle.prototype.on = function (silent) {
|
|
||||||
if (this.$element.prop('disabled')) return false
|
|
||||||
this.$toggle.removeClass(this._offstyle + ' off').addClass(this._onstyle)
|
|
||||||
this.$element.prop('checked', true)
|
|
||||||
if (!silent) this.trigger()
|
|
||||||
}
|
|
||||||
|
|
||||||
Toggle.prototype.off = function (silent) {
|
|
||||||
if (this.$element.prop('disabled')) return false
|
|
||||||
this.$toggle.removeClass(this._onstyle).addClass(this._offstyle + ' off')
|
|
||||||
this.$element.prop('checked', false)
|
|
||||||
if (!silent) this.trigger()
|
|
||||||
}
|
|
||||||
|
|
||||||
Toggle.prototype.enable = function () {
|
|
||||||
this.$toggle.removeAttr('disabled')
|
|
||||||
this.$element.prop('disabled', false)
|
|
||||||
}
|
|
||||||
|
|
||||||
Toggle.prototype.disable = function () {
|
|
||||||
this.$toggle.attr('disabled', 'disabled')
|
|
||||||
this.$element.prop('disabled', true)
|
|
||||||
}
|
|
||||||
|
|
||||||
Toggle.prototype.update = function (silent) {
|
|
||||||
if (this.$element.prop('disabled')) this.disable()
|
|
||||||
else this.enable()
|
|
||||||
if (this.$element.prop('checked')) this.on(silent)
|
|
||||||
else this.off(silent)
|
|
||||||
}
|
|
||||||
|
|
||||||
Toggle.prototype.trigger = function (silent) {
|
|
||||||
this.$element.off('change.bs.toggle')
|
|
||||||
if (!silent) this.$element.change()
|
|
||||||
this.$element.on('change.bs.toggle', $.proxy(function() {
|
|
||||||
this.update()
|
|
||||||
}, this))
|
|
||||||
}
|
|
||||||
|
|
||||||
Toggle.prototype.destroy = function() {
|
|
||||||
this.$element.off('change.bs.toggle')
|
|
||||||
this.$toggleGroup.remove()
|
|
||||||
this.$element.removeData('bs.toggle')
|
|
||||||
this.$element.unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
// TOGGLE PLUGIN DEFINITION
|
|
||||||
// ========================
|
|
||||||
|
|
||||||
function Plugin(option) {
|
|
||||||
return this.each(function () {
|
|
||||||
var $this = $(this)
|
|
||||||
var data = $this.data('bs.toggle')
|
|
||||||
var options = typeof option == 'object' && option
|
|
||||||
|
|
||||||
if (!data) $this.data('bs.toggle', (data = new Toggle(this, options)))
|
|
||||||
if (typeof option == 'string' && data[option]) data[option]()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
var old = $.fn.bootstrapToggle
|
|
||||||
|
|
||||||
$.fn.bootstrapToggle = Plugin
|
|
||||||
$.fn.bootstrapToggle.Constructor = Toggle
|
|
||||||
|
|
||||||
// TOGGLE NO CONFLICT
|
|
||||||
// ==================
|
|
||||||
|
|
||||||
$.fn.toggle.noConflict = function () {
|
|
||||||
$.fn.bootstrapToggle = old
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
// TOGGLE DATA-API
|
|
||||||
// ===============
|
|
||||||
|
|
||||||
$(function() {
|
|
||||||
$('input[type=checkbox][data-toggle^=toggle]').bootstrapToggle()
|
|
||||||
})
|
|
||||||
|
|
||||||
$(document).on('click.bs.toggle', 'div[data-toggle^=toggle]', function(e) {
|
|
||||||
var $checkbox = $(this).find('input[type=checkbox]')
|
|
||||||
$checkbox.bootstrapToggle('toggle')
|
|
||||||
e.preventDefault()
|
|
||||||
})
|
|
||||||
|
|
||||||
}(jQuery);
|
|
|
@ -1,9 +0,0 @@
|
||||||
/*! ========================================================================
|
|
||||||
* Bootstrap Toggle: bootstrap2-toggle.js v2.2.0
|
|
||||||
* http://www.bootstraptoggle.com
|
|
||||||
* ========================================================================
|
|
||||||
* Copyright 2014 Min Hur, The New York Times Company
|
|
||||||
* Licensed under MIT
|
|
||||||
* ======================================================================== */
|
|
||||||
+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.toggle"),f="object"==typeof b&&b;e||d.data("bs.toggle",e=new c(this,f)),"string"==typeof b&&e[b]&&e[b]()})}var c=function(b,c){this.$element=a(b),this.options=a.extend({},this.defaults(),c),this.render()};c.VERSION="2.2.0",c.DEFAULTS={on:"On",off:"Off",onstyle:"primary",offstyle:"default",size:"normal",style:"",width:null,height:null},c.prototype.defaults=function(){return{on:this.$element.attr("data-on")||c.DEFAULTS.on,off:this.$element.attr("data-off")||c.DEFAULTS.off,onstyle:this.$element.attr("data-onstyle")||c.DEFAULTS.onstyle,offstyle:this.$element.attr("data-offstyle")||c.DEFAULTS.offstyle,size:this.$element.attr("data-size")||c.DEFAULTS.size,style:this.$element.attr("data-style")||c.DEFAULTS.style,width:this.$element.attr("data-width")||c.DEFAULTS.width,height:this.$element.attr("data-height")||c.DEFAULTS.height}},c.prototype.render=function(){this._onstyle="btn-"+this.options.onstyle,this._offstyle="btn-"+this.options.offstyle;var b="large"===this.options.size?"btn-large":"small"===this.options.size?"btn-small":"mini"===this.options.size?"btn-mini":"",c=a('<label class="btn">').html(this.options.on).addClass(this._onstyle+" "+b),d=a('<label class="btn">').html(this.options.off).addClass(this._offstyle+" "+b+" active"),e=a('<span class="toggle-handle btn btn-default">').addClass(b),f=a('<div class="toggle-group">').append(c,d,e),g=a('<div class="toggle btn" data-toggle="toggle">').addClass(this.$element.prop("checked")?this._onstyle:this._offstyle+" off").addClass(b).addClass(this.options.style);this.$element.wrap(g),a.extend(this,{$toggle:this.$element.parent(),$toggleOn:c,$toggleOff:d,$toggleGroup:f}),this.$toggle.append(f);var h=this.options.width||Math.max(c.width(),d.width())+e.outerWidth()/2,i=this.options.height||Math.max(c.height(),d.height());c.addClass("toggle-on"),d.addClass("toggle-off"),this.$toggle.css({width:h,height:i}),this.options.height&&(c.css("line-height",c.height()+"px"),d.css("line-height",d.height()+"px")),this.update(!0),this.trigger(!0)},c.prototype.toggle=function(){this.$element.prop("checked")?this.off():this.on()},c.prototype.on=function(a){return this.$element.prop("disabled")?!1:(this.$toggle.removeClass(this._offstyle+" off").addClass(this._onstyle),this.$element.prop("checked",!0),void(a||this.trigger()))},c.prototype.off=function(a){return this.$element.prop("disabled")?!1:(this.$toggle.removeClass(this._onstyle).addClass(this._offstyle+" off"),this.$element.prop("checked",!1),void(a||this.trigger()))},c.prototype.enable=function(){this.$toggle.removeAttr("disabled"),this.$element.prop("disabled",!1)},c.prototype.disable=function(){this.$toggle.attr("disabled","disabled"),this.$element.prop("disabled",!0)},c.prototype.update=function(a){this.$element.prop("disabled")?this.disable():this.enable(),this.$element.prop("checked")?this.on(a):this.off(a)},c.prototype.trigger=function(b){this.$element.off("change.bs.toggle"),b||this.$element.change(),this.$element.on("change.bs.toggle",a.proxy(function(){this.update()},this))},c.prototype.destroy=function(){this.$element.off("change.bs.toggle"),this.$toggleGroup.remove(),this.$element.removeData("bs.toggle"),this.$element.unwrap()};var d=a.fn.bootstrapToggle;a.fn.bootstrapToggle=b,a.fn.bootstrapToggle.Constructor=c,a.fn.toggle.noConflict=function(){return a.fn.bootstrapToggle=d,this},a(function(){a("input[type=checkbox][data-toggle^=toggle]").bootstrapToggle()}),a(document).on("click.bs.toggle","div[data-toggle^=toggle]",function(b){var c=a(this).find("input[type=checkbox]");c.bootstrapToggle("toggle"),b.preventDefault()})}(jQuery);
|
|
||||||
//# sourceMappingURL=bootstrap2-toggle.min.js.map
|
|
|
@ -1 +0,0 @@
|
||||||
{"version":3,"file":"bootstrap2-toggle.min.js","sources":["bootstrap2-toggle.js"],"names":["$","Plugin","option","this","each","$this","data","options","Toggle","element","$element","extend","defaults","render","VERSION","DEFAULTS","on","off","onstyle","offstyle","size","style","width","height","prototype","attr","_onstyle","_offstyle","$toggleOn","html","addClass","$toggleOff","$toggleHandle","$toggleGroup","append","$toggle","prop","wrap","parent","Math","max","outerWidth","css","update","trigger","toggle","silent","removeClass","enable","removeAttr","disable","change","proxy","destroy","remove","removeData","unwrap","old","fn","bootstrapToggle","Constructor","noConflict","document","e","$checkbox","find","preventDefault","jQuery"],"mappings":";;;;;;;CASE,SAAUA,GACV,YAoID,SAASC,GAAOC,GACf,MAAOC,MAAKC,KAAK,WAChB,GAAIC,GAAUL,EAAEG,MACZG,EAAUD,EAAMC,KAAK,aACrBC,EAA2B,gBAAVL,IAAsBA,CAEtCI,IAAMD,EAAMC,KAAK,YAAcA,EAAO,GAAIE,GAAOL,KAAMI,IACvC,gBAAVL,IAAsBI,EAAKJ,IAASI,EAAKJ,OAtItD,GAAIM,GAAS,SAAUC,EAASF,GAC/BJ,KAAKO,SAAYV,EAAES,GACnBN,KAAKI,QAAYP,EAAEW,UAAWR,KAAKS,WAAYL,GAC/CJ,KAAKU,SAGNL,GAAOM,QAAW,QAElBN,EAAOO,UACNC,GAAI,KACJC,IAAK,MACLC,QAAS,UACTC,SAAU,UACVC,KAAM,SACNC,MAAO,GACPC,MAAO,KACPC,OAAQ,MAGTf,EAAOgB,UAAUZ,SAAW,WAC3B,OACCI,GAAIb,KAAKO,SAASe,KAAK,YAAcjB,EAAOO,SAASC,GACrDC,IAAKd,KAAKO,SAASe,KAAK,aAAejB,EAAOO,SAASE,IACvDC,QAASf,KAAKO,SAASe,KAAK,iBAAmBjB,EAAOO,SAASG,QAC/DC,SAAUhB,KAAKO,SAASe,KAAK,kBAAoBjB,EAAOO,SAASI,SACjEC,KAAMjB,KAAKO,SAASe,KAAK,cAAgBjB,EAAOO,SAASK,KACzDC,MAAOlB,KAAKO,SAASe,KAAK,eAAiBjB,EAAOO,SAASM,MAC3DC,MAAOnB,KAAKO,SAASe,KAAK,eAAiBjB,EAAOO,SAASO,MAC3DC,OAAQpB,KAAKO,SAASe,KAAK,gBAAkBjB,EAAOO,SAASQ,SAI/Df,EAAOgB,UAAUX,OAAS,WACzBV,KAAKuB,SAAW,OAASvB,KAAKI,QAAQW,QACtCf,KAAKwB,UAAY,OAASxB,KAAKI,QAAQY,QACvC,IAAIC,GAA6B,UAAtBjB,KAAKI,QAAQa,KAAmB,YAClB,UAAtBjB,KAAKI,QAAQa,KAAmB,YACV,SAAtBjB,KAAKI,QAAQa,KAAkB,WAC/B,GACCQ,EAAY5B,EAAE,uBAAuB6B,KAAK1B,KAAKI,QAAQS,IACzDc,SAAS3B,KAAKuB,SAAW,IAAMN,GAC7BW,EAAa/B,EAAE,uBAAuB6B,KAAK1B,KAAKI,QAAQU,KAC1Da,SAAS3B,KAAKwB,UAAY,IAAMP,EAAO,WACrCY,EAAgBhC,EAAE,gDACpB8B,SAASV,GACPa,EAAejC,EAAE,8BACnBkC,OAAON,EAAWG,EAAYC,GAC5BG,EAAUnC,EAAE,iDACd8B,SAAU3B,KAAKO,SAAS0B,KAAK,WAAajC,KAAKuB,SAAWvB,KAAKwB,UAAU,QACzEG,SAASV,GAAMU,SAAS3B,KAAKI,QAAQc,MAEvClB,MAAKO,SAAS2B,KAAKF,GACnBnC,EAAEW,OAAOR,MACRgC,QAAShC,KAAKO,SAAS4B,SACvBV,UAAWA,EACXG,WAAYA,EACZE,aAAcA,IAEf9B,KAAKgC,QAAQD,OAAOD,EAEpB,IAAIX,GAAQnB,KAAKI,QAAQe,OAASiB,KAAKC,IAAIZ,EAAUN,QAASS,EAAWT,SAAUU,EAAcS,aAAa,EAC1GlB,EAASpB,KAAKI,QAAQgB,QAAUgB,KAAKC,IAAIZ,EAAUL,SAAUQ,EAAWR,SAC5EK,GAAUE,SAAS,aACnBC,EAAWD,SAAS,cACpB3B,KAAKgC,QAAQO,KAAMpB,MAAOA,EAAOC,OAAQA,IACrCpB,KAAKI,QAAQgB,SAChBK,EAAUc,IAAI,cAAed,EAAUL,SAAW,MAClDQ,EAAWW,IAAI,cAAeX,EAAWR,SAAW,OAErDpB,KAAKwC,QAAO,GACZxC,KAAKyC,SAAQ,IAGdpC,EAAOgB,UAAUqB,OAAS,WACrB1C,KAAKO,SAAS0B,KAAK,WAAYjC,KAAKc,MACnCd,KAAKa,MAGXR,EAAOgB,UAAUR,GAAK,SAAU8B,GAC/B,MAAI3C,MAAKO,SAAS0B,KAAK,aAAoB,GAC3CjC,KAAKgC,QAAQY,YAAY5C,KAAKwB,UAAY,QAAQG,SAAS3B,KAAKuB,UAChEvB,KAAKO,SAAS0B,KAAK,WAAW,QACzBU,GAAQ3C,KAAKyC,aAGnBpC,EAAOgB,UAAUP,IAAM,SAAU6B,GAChC,MAAI3C,MAAKO,SAAS0B,KAAK,aAAoB,GAC3CjC,KAAKgC,QAAQY,YAAY5C,KAAKuB,UAAUI,SAAS3B,KAAKwB,UAAY,QAClExB,KAAKO,SAAS0B,KAAK,WAAW,QACzBU,GAAQ3C,KAAKyC,aAGnBpC,EAAOgB,UAAUwB,OAAS,WACzB7C,KAAKgC,QAAQc,WAAW,YACxB9C,KAAKO,SAAS0B,KAAK,YAAY,IAGhC5B,EAAOgB,UAAU0B,QAAU,WAC1B/C,KAAKgC,QAAQV,KAAK,WAAY,YAC9BtB,KAAKO,SAAS0B,KAAK,YAAY,IAGhC5B,EAAOgB,UAAUmB,OAAS,SAAUG,GAC/B3C,KAAKO,SAAS0B,KAAK,YAAajC,KAAK+C,UACpC/C,KAAK6C,SACN7C,KAAKO,SAAS0B,KAAK,WAAYjC,KAAKa,GAAG8B,GACtC3C,KAAKc,IAAI6B,IAGftC,EAAOgB,UAAUoB,QAAU,SAAUE,GACpC3C,KAAKO,SAASO,IAAI,oBACb6B,GAAQ3C,KAAKO,SAASyC,SAC3BhD,KAAKO,SAASM,GAAG,mBAAoBhB,EAAEoD,MAAM,WAC5CjD,KAAKwC,UACHxC,QAGJK,EAAOgB,UAAU6B,QAAU,WAC1BlD,KAAKO,SAASO,IAAI,oBAClBd,KAAK8B,aAAaqB,SAClBnD,KAAKO,SAAS6C,WAAW,aACzBpD,KAAKO,SAAS8C,SAiBf,IAAIC,GAAMzD,EAAE0D,GAAGC,eAEf3D,GAAE0D,GAAGC,gBAA8B1D,EACnCD,EAAE0D,GAAGC,gBAAgBC,YAAcpD,EAKnCR,EAAE0D,GAAGb,OAAOgB,WAAa,WAExB,MADA7D,GAAE0D,GAAGC,gBAAkBF,EAChBtD,MAMRH,EAAE,WACDA,EAAE,6CAA6C2D,oBAGhD3D,EAAE8D,UAAU9C,GAAG,kBAAmB,2BAA4B,SAAS+C,GACtE,GAAIC,GAAYhE,EAAEG,MAAM8D,KAAK,uBAC7BD,GAAUL,gBAAgB,UAC1BI,EAAEG,oBAGFC"}
|
|
|
@ -1,2 +0,0 @@
|
||||||
// Place all the behaviors and hooks related to the matching controller here.
|
|
||||||
// All this logic will automatically be available in application.js.
|
|
|
@ -1,2 +0,0 @@
|
||||||
// Place all the behaviors and hooks related to the matching controller here.
|
|
||||||
// All this logic will automatically be available in application.js.
|
|
|
@ -1,2 +0,0 @@
|
||||||
// Place all the behaviors and hooks related to the matching controller here.
|
|
||||||
// All this logic will automatically be available in application.js.
|
|
|
@ -1,2 +0,0 @@
|
||||||
// Place all the behaviors and hooks related to the matching controller here.
|
|
||||||
// All this logic will automatically be available in application.js.
|
|
|
@ -8,7 +8,6 @@
|
||||||
@import "jquery.mloading";
|
@import "jquery.mloading";
|
||||||
@import "jquery-confirm.min";
|
@import "jquery-confirm.min";
|
||||||
@import "bootstrap-datetimepicker.min";
|
@import "bootstrap-datetimepicker.min";
|
||||||
@import "bootstrap/bootstrap-toggle.min";
|
|
||||||
|
|
||||||
@import "codemirror/lib/codemirror";
|
@import "codemirror/lib/codemirror";
|
||||||
@import "editormd/css/editormd.min";
|
@import "editormd/css/editormd.min";
|
||||||
|
@ -204,14 +203,4 @@ input.form-control {
|
||||||
color: #23272B;
|
color: #23272B;
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.table th, .table td {
|
|
||||||
padding: 0.75rem 0.1rem;
|
|
||||||
vertical-align: top;
|
|
||||||
border-top: 1px solid #dee2e6;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table .thead-light th{
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
}
|
|
@ -1,3 +0,0 @@
|
||||||
// Place all the styles related to the admins/glcc_pr_check controller here.
|
|
||||||
// They will automatically be included in application.css.
|
|
||||||
// You can use Sass (SCSS) here: http://sass-lang.com/
|
|
|
@ -1,3 +0,0 @@
|
||||||
// Place all the styles related to the admins/identity_verifications controller here.
|
|
||||||
// They will automatically be included in application.css.
|
|
||||||
// You can use Sass (SCSS) here: http://sass-lang.com/
|
|
|
@ -1,3 +0,0 @@
|
||||||
// Place all the styles related to the admins/organizations controller here.
|
|
||||||
// They will automatically be included in application.css.
|
|
||||||
// You can use Sass (SCSS) here: http://sass-lang.com/
|
|
|
@ -1,3 +0,0 @@
|
||||||
// Place all the styles related to the admins/page_themes controller here.
|
|
||||||
// They will automatically be included in application.css.
|
|
||||||
// You can use Sass (SCSS) here: http://sass-lang.com/
|
|
|
@ -1,3 +0,0 @@
|
||||||
// Place all the styles related to the admins/site_pages controller here.
|
|
||||||
// They will automatically be included in application.css.
|
|
||||||
// You can use Sass (SCSS) here: http://sass-lang.com/
|
|
|
@ -1,83 +0,0 @@
|
||||||
/*! ========================================================================
|
|
||||||
* Bootstrap Toggle: bootstrap-toggle.css v2.2.0
|
|
||||||
* http://www.bootstraptoggle.com
|
|
||||||
* ========================================================================
|
|
||||||
* Copyright 2014 Min Hur, The New York Times Company
|
|
||||||
* Licensed under MIT
|
|
||||||
* ======================================================================== */
|
|
||||||
|
|
||||||
|
|
||||||
.checkbox label .toggle,
|
|
||||||
.checkbox-inline .toggle {
|
|
||||||
margin-left: -20px;
|
|
||||||
margin-right: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.toggle {
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
.toggle input[type="checkbox"] {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.toggle-group {
|
|
||||||
position: absolute;
|
|
||||||
width: 200%;
|
|
||||||
top: 0;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
transition: left 0.35s;
|
|
||||||
-webkit-transition: left 0.35s;
|
|
||||||
-moz-user-select: none;
|
|
||||||
-webkit-user-select: none;
|
|
||||||
}
|
|
||||||
.toggle.off .toggle-group {
|
|
||||||
left: -100%;
|
|
||||||
}
|
|
||||||
.toggle-on {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 50%;
|
|
||||||
margin: 0;
|
|
||||||
border: 0;
|
|
||||||
border-radius: 0;
|
|
||||||
}
|
|
||||||
.toggle-off {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
bottom: 0;
|
|
||||||
left: 50%;
|
|
||||||
right: 0;
|
|
||||||
margin: 0;
|
|
||||||
border: 0;
|
|
||||||
border-radius: 0;
|
|
||||||
}
|
|
||||||
.toggle-handle {
|
|
||||||
position: relative;
|
|
||||||
margin: 0 auto;
|
|
||||||
padding-top: 0px;
|
|
||||||
padding-bottom: 0px;
|
|
||||||
height: 100%;
|
|
||||||
width: 0px;
|
|
||||||
border-width: 0 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.toggle.btn { min-width: 59px; min-height: 34px; }
|
|
||||||
.toggle-on.btn { padding-right: 24px; }
|
|
||||||
.toggle-off.btn { padding-left: 24px; }
|
|
||||||
|
|
||||||
.toggle.btn-lg { min-width: 79px; min-height: 45px; }
|
|
||||||
.toggle-on.btn-lg { padding-right: 31px; }
|
|
||||||
.toggle-off.btn-lg { padding-left: 31px; }
|
|
||||||
.toggle-handle.btn-lg { width: 40px; }
|
|
||||||
|
|
||||||
.toggle.btn-sm { min-width: 50px; min-height: 30px;}
|
|
||||||
.toggle-on.btn-sm { padding-right: 20px; }
|
|
||||||
.toggle-off.btn-sm { padding-left: 20px; }
|
|
||||||
|
|
||||||
.toggle.btn-xs { min-width: 35px; min-height: 22px;}
|
|
||||||
.toggle-on.btn-xs { padding-right: 12px; }
|
|
||||||
.toggle-off.btn-xs { padding-left: 12px; }
|
|
||||||
|
|
|
@ -1,28 +0,0 @@
|
||||||
/*! ========================================================================
|
|
||||||
* Bootstrap Toggle: bootstrap-toggle.css v2.2.0
|
|
||||||
* http://www.bootstraptoggle.com
|
|
||||||
* ========================================================================
|
|
||||||
* Copyright 2014 Min Hur, The New York Times Company
|
|
||||||
* Licensed under MIT
|
|
||||||
* ======================================================================== */
|
|
||||||
.checkbox label .toggle,.checkbox-inline .toggle{margin-left:-20px;margin-right:5px}
|
|
||||||
.toggle{position:relative;overflow:hidden}
|
|
||||||
.toggle input[type=checkbox]{display:none}
|
|
||||||
.toggle-group{position:absolute;width:200%;top:0;bottom:0;left:0;transition:left .35s;-webkit-transition:left .35s;-moz-user-select:none;-webkit-user-select:none}
|
|
||||||
.toggle.off .toggle-group{left:-100%}
|
|
||||||
.toggle-on{position:absolute;top:0;bottom:0;left:0;right:50%;margin:0;border:0;border-radius:0}
|
|
||||||
.toggle-off{position:absolute;top:0;bottom:0;left:50%;right:0;margin:0;border:0;border-radius:0}
|
|
||||||
.toggle-handle{position:relative;margin:0 auto;padding-top:0;padding-bottom:0;height:100%;width:0;border-width:0 1px}
|
|
||||||
.toggle.btn{min-width:59px;min-height:34px}
|
|
||||||
.toggle-on.btn{padding-right:24px}
|
|
||||||
.toggle-off.btn{padding-left:24px}
|
|
||||||
.toggle.btn-lg{min-width:79px;min-height:45px}
|
|
||||||
.toggle-on.btn-lg{padding-right:31px}
|
|
||||||
.toggle-off.btn-lg{padding-left:31px}
|
|
||||||
.toggle-handle.btn-lg{width:40px}
|
|
||||||
.toggle.btn-sm{min-width:50px;min-height:30px}
|
|
||||||
.toggle-on.btn-sm{padding-right:20px}
|
|
||||||
.toggle-off.btn-sm{padding-left:20px}
|
|
||||||
.toggle.btn-xs{min-width:35px;min-height:22px}
|
|
||||||
.toggle-on.btn-xs{padding-right:12px}
|
|
||||||
.toggle-off.btn-xs{padding-left:12px}
|
|
|
@ -1,85 +0,0 @@
|
||||||
/*! ========================================================================
|
|
||||||
* Bootstrap Toggle: bootstrap2-toggle.css v2.2.0
|
|
||||||
* http://www.bootstraptoggle.com
|
|
||||||
* ========================================================================
|
|
||||||
* Copyright 2014 Min Hur, The New York Times Company
|
|
||||||
* Licensed under MIT
|
|
||||||
* ======================================================================== */
|
|
||||||
|
|
||||||
|
|
||||||
label.checkbox .toggle,
|
|
||||||
label.checkbox.inline .toggle {
|
|
||||||
margin-left: -20px;
|
|
||||||
margin-right: 5px;
|
|
||||||
}
|
|
||||||
.toggle {
|
|
||||||
min-width: 40px;
|
|
||||||
height: 20px;
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
.toggle input[type="checkbox"] {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.toggle-group {
|
|
||||||
position: absolute;
|
|
||||||
width: 200%;
|
|
||||||
top: 0;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
transition: left 0.35s;
|
|
||||||
-webkit-transition: left 0.35s;
|
|
||||||
-moz-user-select: none;
|
|
||||||
-webkit-user-select: none;
|
|
||||||
}
|
|
||||||
.toggle.off .toggle-group {
|
|
||||||
left: -100%;
|
|
||||||
}
|
|
||||||
.toggle-on {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 50%;
|
|
||||||
margin: 0;
|
|
||||||
border: 0;
|
|
||||||
border-radius: 0;
|
|
||||||
}
|
|
||||||
.toggle-off {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
bottom: 0;
|
|
||||||
left: 50%;
|
|
||||||
right: 0;
|
|
||||||
margin: 0;
|
|
||||||
border: 0;
|
|
||||||
border-radius: 0;
|
|
||||||
}
|
|
||||||
.toggle-handle {
|
|
||||||
position: relative;
|
|
||||||
margin: 0 auto;
|
|
||||||
padding-top: 0px;
|
|
||||||
padding-bottom: 0px;
|
|
||||||
height: 100%;
|
|
||||||
width: 0px;
|
|
||||||
border-width: 0 1px;
|
|
||||||
}
|
|
||||||
.toggle-handle.btn-mini {
|
|
||||||
top: -1px;
|
|
||||||
}
|
|
||||||
.toggle.btn { min-width: 30px; }
|
|
||||||
.toggle-on.btn { padding-right: 24px; }
|
|
||||||
.toggle-off.btn { padding-left: 24px; }
|
|
||||||
|
|
||||||
.toggle.btn-large { min-width: 40px; }
|
|
||||||
.toggle-on.btn-large { padding-right: 35px; }
|
|
||||||
.toggle-off.btn-large { padding-left: 35px; }
|
|
||||||
|
|
||||||
.toggle.btn-small { min-width: 25px; }
|
|
||||||
.toggle-on.btn-small { padding-right: 20px; }
|
|
||||||
.toggle-off.btn-small { padding-left: 20px; }
|
|
||||||
|
|
||||||
.toggle.btn-mini { min-width: 20px; }
|
|
||||||
.toggle-on.btn-mini { padding-right: 12px; }
|
|
||||||
.toggle-off.btn-mini { padding-left: 12px; }
|
|
||||||
|
|
|
@ -1,28 +0,0 @@
|
||||||
/*! ========================================================================
|
|
||||||
* Bootstrap Toggle: bootstrap2-toggle.css v2.2.0
|
|
||||||
* http://www.bootstraptoggle.com
|
|
||||||
* ========================================================================
|
|
||||||
* Copyright 2014 Min Hur, The New York Times Company
|
|
||||||
* Licensed under MIT
|
|
||||||
* ======================================================================== */
|
|
||||||
label.checkbox .toggle,label.checkbox.inline .toggle{margin-left:-20px;margin-right:5px}
|
|
||||||
.toggle{min-width:40px;height:20px;position:relative;overflow:hidden}
|
|
||||||
.toggle input[type=checkbox]{display:none}
|
|
||||||
.toggle-group{position:absolute;width:200%;top:0;bottom:0;left:0;transition:left .35s;-webkit-transition:left .35s;-moz-user-select:none;-webkit-user-select:none}
|
|
||||||
.toggle.off .toggle-group{left:-100%}
|
|
||||||
.toggle-on{position:absolute;top:0;bottom:0;left:0;right:50%;margin:0;border:0;border-radius:0}
|
|
||||||
.toggle-off{position:absolute;top:0;bottom:0;left:50%;right:0;margin:0;border:0;border-radius:0}
|
|
||||||
.toggle-handle{position:relative;margin:0 auto;padding-top:0;padding-bottom:0;height:100%;width:0;border-width:0 1px}
|
|
||||||
.toggle-handle.btn-mini{top:-1px}
|
|
||||||
.toggle.btn{min-width:30px}
|
|
||||||
.toggle-on.btn{padding-right:24px}
|
|
||||||
.toggle-off.btn{padding-left:24px}
|
|
||||||
.toggle.btn-large{min-width:40px}
|
|
||||||
.toggle-on.btn-large{padding-right:35px}
|
|
||||||
.toggle-off.btn-large{padding-left:35px}
|
|
||||||
.toggle.btn-small{min-width:25px}
|
|
||||||
.toggle-on.btn-small{padding-right:20px}
|
|
||||||
.toggle-off.btn-small{padding-left:20px}
|
|
||||||
.toggle.btn-mini{min-width:20px}
|
|
||||||
.toggle-on.btn-mini{padding-right:12px}
|
|
||||||
.toggle-off.btn-mini{padding-left:12px}
|
|
|
@ -1,3 +0,0 @@
|
||||||
// Place all the styles related to the identity_verifications controller here.
|
|
||||||
// They will automatically be included in application.css.
|
|
||||||
// You can use Sass (SCSS) here: http://sass-lang.com/
|
|
|
@ -1,3 +0,0 @@
|
||||||
// Place all the styles related to the organizations/clas controller here.
|
|
||||||
// They will automatically be included in application.css.
|
|
||||||
// You can use Sass (SCSS) here: http://sass-lang.com/
|
|
|
@ -1,3 +0,0 @@
|
||||||
// Place all the styles related to the pages controller here.
|
|
||||||
// They will automatically be included in application.css.
|
|
||||||
// You can use Sass (SCSS) here: http://sass-lang.com/
|
|
|
@ -1,3 +0,0 @@
|
||||||
// Place all the styles related to the users/clas controller here.
|
|
||||||
// They will automatically be included in application.css.
|
|
||||||
// You can use Sass (SCSS) here: http://sass-lang.com/
|
|
|
@ -1,26 +1,6 @@
|
||||||
class AccountsController < ApplicationController
|
class AccountsController < ApplicationController
|
||||||
before_action :require_login, only: [:login_check, :simple_update]
|
|
||||||
include ApplicationHelper
|
include ApplicationHelper
|
||||||
|
|
||||||
#skip_before_action :check_account, :only => [:logout]
|
|
||||||
|
|
||||||
def simple_update
|
|
||||||
simple_update_params.merge!(username: params[:username]&.gsub(/\s+/, ""))
|
|
||||||
simple_update_params.merge!(email: params[:email]&.gsub(/\s+/, ""))
|
|
||||||
simple_update_params.merge!(platform: (params[:platform] || 'forge')&.gsub(/\s+/, ""))
|
|
||||||
Register::RemoteForm.new(simple_update_params.merge(user_id: current_user.id)).validate!
|
|
||||||
|
|
||||||
ActiveRecord::Base.transaction do
|
|
||||||
result = auto_update(current_user, simple_update_params)
|
|
||||||
if result[:message].blank?
|
|
||||||
UserAction.create(:action_id => current_user.id, :action_type => "sync_educoder_user", :user_id => current_user.id, :ip => request.remote_ip) if params[:platform] == "educoder"
|
|
||||||
render_ok
|
|
||||||
else
|
|
||||||
render_error(result[:message])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def index
|
def index
|
||||||
render json: session
|
render json: session
|
||||||
end
|
end
|
||||||
|
@ -112,9 +92,7 @@ class AccountsController < ApplicationController
|
||||||
|
|
||||||
sync_params = {
|
sync_params = {
|
||||||
password: params[:password].to_s,
|
password: params[:password].to_s,
|
||||||
email: @user.mail,
|
email: @user.mail
|
||||||
login_name: @user.login,
|
|
||||||
source_id: 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interactor = Gitea::User::UpdateInteractor.call(@user.login, sync_params)
|
interactor = Gitea::User::UpdateInteractor.call(@user.login, sync_params)
|
||||||
|
@ -142,7 +120,6 @@ class AccountsController < ApplicationController
|
||||||
Register::Form.new(register_params).validate!
|
Register::Form.new(register_params).validate!
|
||||||
|
|
||||||
user = Users::RegisterService.call(register_params)
|
user = Users::RegisterService.call(register_params)
|
||||||
user.mail = "#{user.login}@example.org" if user.mail.blank?
|
|
||||||
password = register_params[:password].strip
|
password = register_params[:password].strip
|
||||||
|
|
||||||
# gitea用户注册, email, username, password
|
# gitea用户注册, email, username, password
|
||||||
|
@ -154,18 +131,11 @@ class AccountsController < ApplicationController
|
||||||
user.gitea_uid = gitea_user[:body]['id']
|
user.gitea_uid = gitea_user[:body]['id']
|
||||||
if user.save!
|
if user.save!
|
||||||
UserExtension.create!(user_id: user.id)
|
UserExtension.create!(user_id: user.id)
|
||||||
# 绑定授权账号
|
|
||||||
if ["qq", "wechat", "gitee", "github", "educoder"].include?(params[:type].to_s) && session[:unionid].present?
|
|
||||||
"OpenUsers::#{params[:type].to_s.capitalize}".constantize.create!(user: user, uid: session[:unionid])
|
|
||||||
end
|
|
||||||
successful_authentication(user)
|
successful_authentication(user)
|
||||||
render_ok
|
render_ok
|
||||||
end
|
end
|
||||||
elsif interactor.result[:message].to_s.include?("user already exists")
|
|
||||||
UserAction.create(:action_id => 2, :action_type => "register_error", :user_id => user.try(:id).to_i, :ip => "code: #{register_params[:code]}; login: #{register_params[:login]}; namespace: #{register_params[:namespace]}; password: #{password};")
|
|
||||||
normal_status(-1, "用户已注册,请勿连续操作。")
|
|
||||||
else
|
else
|
||||||
tip_exception(-1, interactor.result[:message])
|
tip_exception(-1, interactor.error)
|
||||||
end
|
end
|
||||||
rescue Register::BaseForm::EmailError => e
|
rescue Register::BaseForm::EmailError => e
|
||||||
render_result(-2, e.message)
|
render_result(-2, e.message)
|
||||||
|
@ -180,14 +150,9 @@ class AccountsController < ApplicationController
|
||||||
rescue Register::BaseForm::VerifiCodeError => e
|
rescue Register::BaseForm::VerifiCodeError => e
|
||||||
render_result(-6, e.message)
|
render_result(-6, e.message)
|
||||||
rescue Exception => e
|
rescue Exception => e
|
||||||
if user.present? && !e.message.to_s.include?("user already exists")
|
Gitea::User::DeleteService.call(user.login) unless user.nil?
|
||||||
# Gitea::User::DeleteService.call(user.login)
|
uid_logger_error(e.message)
|
||||||
# user.destroy
|
tip_exception(-1, e.message)
|
||||||
end
|
|
||||||
Rails.logger.error("##:register error--#{user.try(:id)},message:#{e.message}")
|
|
||||||
UserAction.create(:action_id => 1, :action_type => "register_error", :user_id => user.try(:id).to_i, :ip => "code: #{register_params[:code]}; login: #{register_params[:login]}; namespace: #{register_params[:namespace]}; password: #{password};")
|
|
||||||
logger_error(e)
|
|
||||||
tip_exception(-1, "注册失败")
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -201,12 +166,12 @@ class AccountsController < ApplicationController
|
||||||
return normal_status(-2, "违反平台使用规范,账号已被锁定") if @user.locked?
|
return normal_status(-2, "违反平台使用规范,账号已被锁定") if @user.locked?
|
||||||
|
|
||||||
login_control = LimitForbidControl::UserLogin.new(@user)
|
login_control = LimitForbidControl::UserLogin.new(@user)
|
||||||
return normal_status(-2, "登录密码出错已达上限,账号已被锁定,请#{login_control.forbid_expires/60}分钟后重新登录或找回密码") if login_control.forbid?
|
return normal_status(-2, "登录密码出错已达上限,账号已被锁定, 请#{login_control.forbid_expires/60}分钟后重新登录或找回密码") if login_control.forbid?
|
||||||
|
|
||||||
password_ok = @user.check_password?(params[:password].to_s)
|
password_ok = @user.check_password?(params[:password].to_s)
|
||||||
unless password_ok
|
unless password_ok
|
||||||
if login_control.remain_times-1 == 0
|
if login_control.remain_times-1 == 0
|
||||||
normal_status(-2, "登录密码出错已达上限,账号已被锁定,请#{login_control.forbid_expires/60}分钟后重新登录或找回密码")
|
normal_status(-2, "登录密码出错已达上限,账号已被锁定, 请#{login_control.forbid_expires/60}分钟后重新登录或找回密码")
|
||||||
else
|
else
|
||||||
normal_status(-2, "你已经输错密码#{login_control.error_times+1}次,还剩余#{login_control.remain_times-1}次机会")
|
normal_status(-2, "你已经输错密码#{login_control.error_times+1}次,还剩余#{login_control.remain_times-1}次机会")
|
||||||
end
|
end
|
||||||
|
@ -214,17 +179,14 @@ class AccountsController < ApplicationController
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
LimitForbidControl::UserLogin.new(@user).clear
|
|
||||||
successful_authentication(@user)
|
successful_authentication(@user)
|
||||||
sync_pwd_to_gitea!(@user, {password: params[:password].to_s}) # TODO用户密码未同步
|
sync_pwd_to_gitea!(@user, {password: params[:password].to_s}) # TODO用户密码未同步
|
||||||
|
|
||||||
# session[:user_id] = @user.id
|
# session[:user_id] = @user.id
|
||||||
end
|
end
|
||||||
|
|
||||||
def change_password
|
def change_password
|
||||||
return render_error("两次输入的密码不一致") if params[:password].to_s != params[:new_password_repeat].to_s
|
|
||||||
@user = User.find_by(login: params[:login])
|
@user = User.find_by(login: params[:login])
|
||||||
return render_error("此用户禁止修改密码!") if @user.id.to_i === 104691
|
|
||||||
return render_error("未找到相关用户!") if @user.blank?
|
return render_error("未找到相关用户!") if @user.blank?
|
||||||
return render_error("旧密码不正确") unless @user.check_password?(params[:old_password])
|
return render_error("旧密码不正确") unless @user.check_password?(params[:old_password])
|
||||||
|
|
||||||
|
@ -335,8 +297,6 @@ class AccountsController < ApplicationController
|
||||||
send_type = verify_type(login_type, type)
|
send_type = verify_type(login_type, type)
|
||||||
verification_code = code.sample(6).join
|
verification_code = code.sample(6).join
|
||||||
|
|
||||||
status, message = InfoRiskControlService.call(value, request.remote_ip)
|
|
||||||
tip_exception(420, message) if status == 0
|
|
||||||
sign = Digest::MD5.hexdigest("#{OPENKEY}#{value}")
|
sign = Digest::MD5.hexdigest("#{OPENKEY}#{value}")
|
||||||
tip_exception(501, "请求不合理") if sign != params[:smscode]
|
tip_exception(501, "请求不合理") if sign != params[:smscode]
|
||||||
|
|
||||||
|
@ -355,22 +315,6 @@ class AccountsController < ApplicationController
|
||||||
Register::CheckColumnsForm.new(check_params).validate!
|
Register::CheckColumnsForm.new(check_params).validate!
|
||||||
render_ok
|
render_ok
|
||||||
end
|
end
|
||||||
|
|
||||||
def login_check
|
|
||||||
Register::LoginCheckColumnsForm.new(check_params.merge(user: current_user)).validate!
|
|
||||||
render_ok
|
|
||||||
end
|
|
||||||
|
|
||||||
def check_keywords
|
|
||||||
text = params[:text].to_s.each_char.select { |c| c.bytes.first < 240 }.join('')
|
|
||||||
data = ! ReversedKeyword.check_exists?(text)
|
|
||||||
result = {
|
|
||||||
status: 0,
|
|
||||||
data: data,
|
|
||||||
message: data ? "" : "无法使用以下关键词:#{text},请重新命名"
|
|
||||||
}
|
|
||||||
render_ok(result)
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
@ -423,7 +367,7 @@ class AccountsController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def register_params
|
def register_params
|
||||||
params.permit(:login, :namespace, :password, :password_confirmation, :code, :type)
|
params.permit(:login, :namespace, :password, :password_confirmation, :code)
|
||||||
end
|
end
|
||||||
|
|
||||||
def reset_password_params
|
def reset_password_params
|
||||||
|
@ -439,7 +383,4 @@ class AccountsController < ApplicationController
|
||||||
params.permit(:username, :email, :password, :platform)
|
params.permit(:username, :email, :password, :platform)
|
||||||
end
|
end
|
||||||
|
|
||||||
def simple_update_params
|
|
||||||
params.permit(:username, :email, :password, :platform)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,75 +0,0 @@
|
||||||
class Action::NodeInputsController < ApplicationController
|
|
||||||
before_action :require_admin, except: [:index]
|
|
||||||
before_action :find_action_node
|
|
||||||
|
|
||||||
def index
|
|
||||||
@node_inputs = @node.action_node_inputs
|
|
||||||
respond_to do |format|
|
|
||||||
format.html
|
|
||||||
format.json
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def create
|
|
||||||
@node_input = Action::NodeInput.new(node_input_params)
|
|
||||||
@node_input.action_node = @node
|
|
||||||
respond_to do |format|
|
|
||||||
if @node_input.save
|
|
||||||
format.html { redirect_to action_node_node_inputs_path(@node), notice: '创建成功.' }
|
|
||||||
format.json { render_ok(data: @node_input.as_json) }
|
|
||||||
else
|
|
||||||
format.html { render :new }
|
|
||||||
format.json { render json: @node_input.errors, status: -1 }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def new
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
def show
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
def edit
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
def update
|
|
||||||
@node_input.update(node_input_params)
|
|
||||||
respond_to do |format|
|
|
||||||
format.html { redirect_to action_node_node_inputs_path(@node), notice: '更新成功.' }
|
|
||||||
format.json { render_ok(data: @node_input.as_json) }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def destroy
|
|
||||||
if @node_input.destroy!
|
|
||||||
flash[:success] = '删除成功'
|
|
||||||
else
|
|
||||||
flash[:danger] = '删除失败'
|
|
||||||
end
|
|
||||||
redirect_to "api/actions/nodes"
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def find_action_node
|
|
||||||
@node = Action::Node.find(params[:node_id])
|
|
||||||
if params[:id].present?
|
|
||||||
@node_input = @node.action_node_inputs.find(params[:id])
|
|
||||||
else
|
|
||||||
@node_input = Action::NodeInput.new
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
def node_input_params
|
|
||||||
if params.require(:action_node_input)
|
|
||||||
params.require(:action_node_input).permit(:name, :input_type, :description, :is_required, :sort_no)
|
|
||||||
else
|
|
||||||
params.permit(:name, :input_type, :description, :is_required, :sort_no)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,76 +0,0 @@
|
||||||
class Action::NodeSelectsController < ApplicationController
|
|
||||||
|
|
||||||
before_action :require_admin, except: [:index]
|
|
||||||
before_action :find_action_node
|
|
||||||
|
|
||||||
def index
|
|
||||||
@node_selects = @node.action_node_selects
|
|
||||||
respond_to do |format|
|
|
||||||
format.html
|
|
||||||
format.json
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def create
|
|
||||||
@node_select = Action::NodeSelect.new(node_select_params)
|
|
||||||
@node_select.action_node = @node
|
|
||||||
respond_to do |format|
|
|
||||||
if @node_select.save
|
|
||||||
format.html { redirect_to action_node_node_selects_path(@node), notice: '创建成功.' }
|
|
||||||
format.json { render_ok(data: @node_select.as_json) }
|
|
||||||
else
|
|
||||||
format.html { render :new }
|
|
||||||
format.json { render json: @node_select.errors, status: -1 }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def new
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
def show
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
def edit
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
def update
|
|
||||||
@node_select.update(node_select_params)
|
|
||||||
respond_to do |format|
|
|
||||||
format.html { redirect_to action_node_node_selects_path(@node), notice: '更新成功.' }
|
|
||||||
format.json { render_ok(data: @node_select.as_json) }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def destroy
|
|
||||||
if @node_select.destroy!
|
|
||||||
flash[:success] = '删除成功'
|
|
||||||
else
|
|
||||||
flash[:danger] = '删除失败'
|
|
||||||
end
|
|
||||||
redirect_to "api/actions/nodes"
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def find_action_node
|
|
||||||
@node = Action::Node.find(params[:node_id])
|
|
||||||
if params[:id].present?
|
|
||||||
@node_select = @node.action_node_selects.find(params[:id])
|
|
||||||
else
|
|
||||||
@node_select = Action::NodeSelect.new
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
def node_select_params
|
|
||||||
if params.require(:action_node_select)
|
|
||||||
params.require(:action_node_select).permit(:name, :val, :val_ext, :description, :sort_no)
|
|
||||||
else
|
|
||||||
params.permit(:name, :val, :val_ext, :description, :sort_no)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,64 +0,0 @@
|
||||||
class Action::NodeTypesController < ApplicationController
|
|
||||||
before_action :require_admin, except: [:index]
|
|
||||||
before_action :find_node_type, except: [:index, :create, :new]
|
|
||||||
|
|
||||||
def index
|
|
||||||
@node_types = Action::NodeType.all
|
|
||||||
end
|
|
||||||
|
|
||||||
def create
|
|
||||||
@node_type = Action::NodeType.new(node_types_params)
|
|
||||||
respond_to do |format|
|
|
||||||
if @node_type.save
|
|
||||||
format.html { redirect_to action_node_types_path, notice: '创建成功.' }
|
|
||||||
format.json { render_ok(data: @node_type.as_json) }
|
|
||||||
else
|
|
||||||
format.html { render :new }
|
|
||||||
format.json { render json: @node_type.errors, status: -1 }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def show
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
def new
|
|
||||||
@node_type = Action::NodeType.new
|
|
||||||
end
|
|
||||||
|
|
||||||
def edit
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
def update
|
|
||||||
@node_type.update(node_types_params)
|
|
||||||
respond_to do |format|
|
|
||||||
format.html { redirect_to action_node_types_path, notice: '更新成功.' }
|
|
||||||
format.json { render_ok(data: @node_type.as_json) }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def destroy
|
|
||||||
if @node_type.destroy!
|
|
||||||
flash[:success] = '删除成功'
|
|
||||||
else
|
|
||||||
flash[:danger] = '删除失败'
|
|
||||||
end
|
|
||||||
redirect_to action_node_types_path
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def find_node_type
|
|
||||||
@node_type = Action::NodeType.find(params[:id])
|
|
||||||
end
|
|
||||||
|
|
||||||
def node_types_params
|
|
||||||
if params.require(:action_node_type)
|
|
||||||
params.require(:action_node_type).permit(:name, :description, :sort_no)
|
|
||||||
else
|
|
||||||
params.permit(:name, :description, :sort_no)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,69 +0,0 @@
|
||||||
class Action::NodesController < ApplicationController
|
|
||||||
before_action :require_admin, except: [:index]
|
|
||||||
before_action :find_action_node, except: [:index, :create, :new]
|
|
||||||
|
|
||||||
def index
|
|
||||||
@node_types = Action::NodeType.all
|
|
||||||
@no_type_nodes = Action::Node.where(action_node_types_id: nil)
|
|
||||||
respond_to do |format|
|
|
||||||
format.html { @nodes = Action::Node.all }
|
|
||||||
format.json
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def create
|
|
||||||
@node = Action::Node.new(node_params)
|
|
||||||
respond_to do |format|
|
|
||||||
if @node.save
|
|
||||||
format.html { redirect_to action_nodes_path, notice: '创建成功.' }
|
|
||||||
format.json { render_ok(data: @node.as_json) }
|
|
||||||
else
|
|
||||||
format.html { render :new }
|
|
||||||
format.json { render json: @node.errors, status: -1 }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def new
|
|
||||||
@node = Action::Node.new
|
|
||||||
end
|
|
||||||
|
|
||||||
def show
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
def edit
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
def update
|
|
||||||
@node.update(node_params)
|
|
||||||
respond_to do |format|
|
|
||||||
format.html { redirect_to action_nodes_path, notice: '更新成功.' }
|
|
||||||
format.json { render_ok(data: @node.as_json) }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def destroy
|
|
||||||
if @node.destroy!
|
|
||||||
flash[:success] = '删除成功'
|
|
||||||
else
|
|
||||||
flash[:danger] = '删除失败'
|
|
||||||
end
|
|
||||||
redirect_to action_nodes_path
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def find_action_node
|
|
||||||
@node = Action::Node.find(params[:id])
|
|
||||||
end
|
|
||||||
|
|
||||||
def node_params
|
|
||||||
if params.require(:action_node)
|
|
||||||
params.require(:action_node).permit(:name, :full_name, :description, :icon, :action_node_types_id, :is_local, :local_url, :yaml, :sort_no)
|
|
||||||
else
|
|
||||||
params.permit(:name, :full_name, :description, :icon, :action_node_types_id, :is_local, :local_url, :yaml, :sort_no)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,68 +0,0 @@
|
||||||
class Action::TemplatesController < ApplicationController
|
|
||||||
before_action :require_admin, except: [:index]
|
|
||||||
before_action :find_action_template, except: [:index, :create, :new]
|
|
||||||
|
|
||||||
def index
|
|
||||||
@templates = Action::Template.all
|
|
||||||
respond_to do |format|
|
|
||||||
format.html
|
|
||||||
format.json
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def create
|
|
||||||
@template = Action::Template.new(templates_params)
|
|
||||||
respond_to do |format|
|
|
||||||
if @template.save
|
|
||||||
format.html { redirect_to action_templates_path, notice: '创建成功.' }
|
|
||||||
format.json { render_ok(data: @template.as_json) }
|
|
||||||
else
|
|
||||||
format.html { render :new }
|
|
||||||
format.json { render json: @template.errors, status: -1 }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def show
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
def new
|
|
||||||
@template = Action::Template.new
|
|
||||||
end
|
|
||||||
|
|
||||||
def edit
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
def update
|
|
||||||
@template.update(templates_params)
|
|
||||||
respond_to do |format|
|
|
||||||
format.html { redirect_to action_templates_path, notice: '更新成功.' }
|
|
||||||
format.json { render_ok(data: @template.as_json) }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def destroy
|
|
||||||
if @template.destroy!
|
|
||||||
flash[:success] = '删除成功'
|
|
||||||
else
|
|
||||||
flash[:danger] = '删除失败'
|
|
||||||
end
|
|
||||||
redirect_to action_templates_path
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def find_action_template
|
|
||||||
@template = Action::Template.find(params[:id])
|
|
||||||
end
|
|
||||||
|
|
||||||
def templates_params
|
|
||||||
if params.require(:action_template)
|
|
||||||
params.require(:action_template).permit(:name, :description, :img, :sort_no, :json, :yaml)
|
|
||||||
else
|
|
||||||
params.permit(:name, :description, :img, :sort_no, :json, :yaml)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -23,23 +23,10 @@ class Admins::BaseController < ApplicationController
|
||||||
def require_admin!
|
def require_admin!
|
||||||
return if current_user.blank? || !current_user.logged?
|
return if current_user.blank? || !current_user.logged?
|
||||||
return if current_user.admin_or_business?
|
return if current_user.admin_or_business?
|
||||||
return if current_user.admin_or_glcc_admin?
|
|
||||||
|
|
||||||
render_forbidden
|
render_forbidden
|
||||||
end
|
end
|
||||||
|
|
||||||
def require_admin
|
|
||||||
render_forbidden unless User.current.admin?
|
|
||||||
end
|
|
||||||
|
|
||||||
def require_business
|
|
||||||
render_forbidden unless admin_or_business?
|
|
||||||
end
|
|
||||||
|
|
||||||
def require_glcc_admin
|
|
||||||
render_forbidden unless admin_or_glcc_admin?
|
|
||||||
end
|
|
||||||
|
|
||||||
# 触发after ajax render partial hooks,执行一些因为局部刷新后失效的绑定事件
|
# 触发after ajax render partial hooks,执行一些因为局部刷新后失效的绑定事件
|
||||||
def rebind_event_if_ajax_render_partial
|
def rebind_event_if_ajax_render_partial
|
||||||
return if request.format.symbol != :js
|
return if request.format.symbol != :js
|
||||||
|
|
|
@ -1,99 +1,10 @@
|
||||||
class Admins::DashboardsController < Admins::BaseController
|
class Admins::DashboardsController < Admins::BaseController
|
||||||
def index
|
def index
|
||||||
# 查询优化
|
@active_user_count = User.where(last_login_on: today).count
|
||||||
week_greater_id = CommitLog.where(created_at: current_week).limit(1)[0]&.id
|
@weekly_active_user_count = User.where(last_login_on: current_week).count
|
||||||
#月份统计还需要优化
|
@month_active_user_count = User.where(last_login_on: current_month).count
|
||||||
month_greater_id = CommitLog.where(created_at: current_month).limit(1)[0]&.id
|
|
||||||
# 用户活跃数
|
|
||||||
day_user_ids = CommitLog.where(created_at: today).pluck(:user_id).uniq
|
|
||||||
weekly_user_ids = CommitLog.where(created_at: current_week).where("id>= ?", week_greater_id).distinct.pluck(:user_id)
|
|
||||||
month_user_ids = CommitLog.where(created_at: current_month).where("id>= ?", month_greater_id).distinct.pluck(:user_id)
|
|
||||||
@active_user_count = User.where(last_login_on: today).or(User.where(id: day_user_ids)).count
|
|
||||||
@weekly_active_user_count = User.where(last_login_on: current_week).or(User.where(id: weekly_user_ids)).count
|
|
||||||
@month_active_user_count = User.where(last_login_on: current_month).or(User.where(id: month_user_ids)).count
|
|
||||||
user_ids = User.where(created_on: pre_week).pluck(:id).uniq
|
|
||||||
weekly_keep_user_count = User.where(id: user_ids).where(last_login_on: current_week).count
|
|
||||||
@weekly_keep_rate = format("%.2f", user_ids.size > 0 ? weekly_keep_user_count.to_f / user_ids.size : 0)
|
|
||||||
|
|
||||||
# 新用户注册数
|
|
||||||
@day_new_user_count = User.where(created_on: today).count
|
|
||||||
@weekly_new_user_count = User.where(created_on: current_week).count
|
|
||||||
@month_new_user_count = User.where(created_on: current_month).count
|
|
||||||
|
|
||||||
# 活跃项目数
|
|
||||||
day_project_ids = (CommitLog.where(created_at: today).pluck(:project_id).uniq + Issue.where(created_on: today).pluck(:project_id).uniq).uniq
|
|
||||||
weekly_project_ids = (CommitLog.where(created_at: current_week).where("id>= ?", week_greater_id).distinct.pluck(:project_id) + Issue.where(created_on: current_week).pluck(:project_id).uniq).uniq
|
|
||||||
month_project_ids = (CommitLog.where(created_at: current_month).where("id>= ?", month_greater_id).distinct.pluck(:project_id) + Issue.where(created_on: current_month).pluck(:project_id).uniq).uniq
|
|
||||||
@day_active_project_count = Project.where(updated_on: today).or(Project.where(id: day_project_ids)).count
|
|
||||||
@weekly_active_project_count = Rails.cache.fetch("dashboardscontroller:weekly_active_project_count", expires_in: 10.minutes) do
|
|
||||||
Project.where(updated_on: current_week).or(Project.where(id: weekly_project_ids)).count
|
|
||||||
end
|
|
||||||
@month_active_project_count = Rails.cache.fetch("dashboardscontroller:month_active_project_count", expires_in: 1.hours) do
|
|
||||||
Project.where(updated_on: current_month).or(Project.where(id: month_project_ids)).count
|
|
||||||
end
|
|
||||||
# 新增项目数
|
|
||||||
@day_new_project_count = Rails.cache.fetch("dashboardscontroller:day_new_project_count", expires_in: 10.minutes) do
|
|
||||||
Project.where(created_on: today).count
|
|
||||||
end
|
|
||||||
@weekly_new_project_count = Rails.cache.fetch("dashboardscontroller:weekly_new_project_count", expires_in: 10.minutes) do
|
|
||||||
Project.where(created_on: current_week).count
|
|
||||||
end
|
|
||||||
@month_new_project_count = Rails.cache.fetch("dashboardscontroller:month_new_project_count", expires_in: 1.hours) do
|
|
||||||
Project.where(created_on: current_month).count
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
# 总的平台用户数
|
|
||||||
# 总的平台项目数
|
|
||||||
# 总的平台组织数
|
|
||||||
# 总的平台Issue数、评论数、PR数、Commit数
|
|
||||||
@user_count = Rails.cache.fetch("dashboardscontroller:platform:user_count", expires_in: 1.days) do
|
|
||||||
User.count
|
|
||||||
end
|
|
||||||
@project_count = Rails.cache.fetch("dashboardscontroller:platform:project_count", expires_in: 1.days) do
|
|
||||||
Project.count
|
|
||||||
end
|
|
||||||
@organization_count = Rails.cache.fetch("dashboardscontroller:platform:organization_count", expires_in: 1.days) do
|
|
||||||
Organization.count
|
|
||||||
end
|
|
||||||
@issue_count = Rails.cache.fetch("dashboardscontroller:platform:issue_count", expires_in: 1.days) do
|
|
||||||
Issue.count
|
|
||||||
end
|
|
||||||
@comment_count = Rails.cache.fetch("dashboardscontroller:platform:comment_count", expires_in: 1.days) do
|
|
||||||
Journal.count
|
|
||||||
end
|
|
||||||
@pr_count = Rails.cache.fetch("dashboardscontroller:platform:pr_count", expires_in: 1.days) do
|
|
||||||
PullRequest.count
|
|
||||||
end
|
|
||||||
@commit_count = Rails.cache.fetch("dashboardscontroller:platform:commit_count", expires_in: 1.days) do
|
|
||||||
CommitLog.count
|
|
||||||
end
|
|
||||||
|
|
||||||
@subject_name = ["用户数", "项目数", "组织数", "Issue数", "Issue评论数", "PR数", "Commit数"]
|
|
||||||
@subject_icon = ["fa-user","fa-git", "fa-sitemap", "fa-warning", "fa-comments", "fa-share-alt", "fa-upload"]
|
|
||||||
@subject_data = [@user_count, @project_count, @organization_count, @issue_count, @comment_count, @pr_count, @commit_count]
|
|
||||||
|
|
||||||
|
|
||||||
tongji_service = Baidu::TongjiService.new
|
|
||||||
@access_token = tongji_service.access_token
|
|
||||||
Rails.logger.info "baidu_tongji_auth access_token ===== #{@access_token}"
|
|
||||||
# @overview_data = tongji_service.api_overview
|
|
||||||
last_date = DailyPlatformStatistic.order(:date).last
|
|
||||||
start_date = last_date.date
|
|
||||||
end_date = Time.now
|
|
||||||
if @access_token.present?
|
|
||||||
@overview_data = Rails.cache.fetch("dashboardscontroller:baidu_tongji:overview_data", expires_in: 10.minutes) do
|
|
||||||
tongji_service.source_from_batch_add(start_date, end_date)
|
|
||||||
@overview_data = tongji_service.overview_batch_add(start_date, end_date)
|
|
||||||
@overview_data
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
@current_week_statistic = DailyPlatformStatistic.where(date: current_week)
|
|
||||||
@pre_week_statistic = DailyPlatformStatistic.where(date: pre_week)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@new_user_count = User.where(created_on: current_month).count
|
||||||
end
|
end
|
||||||
|
|
||||||
def month_active_user
|
def month_active_user
|
||||||
|
@ -105,22 +16,10 @@ class Admins::DashboardsController < Admins::BaseController
|
||||||
{ value: count['professional'].to_i, name: '专业人士' },
|
{ value: count['professional'].to_i, name: '专业人士' },
|
||||||
{ value: count[nil].to_i, name: '未选职业' },
|
{ value: count[nil].to_i, name: '未选职业' },
|
||||||
]
|
]
|
||||||
|
|
||||||
render_ok(data: data)
|
render_ok(data: data)
|
||||||
end
|
end
|
||||||
|
|
||||||
def baidu_tongji
|
|
||||||
tongji_service = Baidu::TongjiService.new
|
|
||||||
redirect_to tongji_service.code_url
|
|
||||||
end
|
|
||||||
|
|
||||||
def baidu_tongji_auth
|
|
||||||
if params[:code].present?
|
|
||||||
tongji_service = Baidu::TongjiService.new
|
|
||||||
tongji_service.get_access_token(params[:code])
|
|
||||||
end
|
|
||||||
redirect_to "/admins/"
|
|
||||||
end
|
|
||||||
|
|
||||||
def evaluate
|
def evaluate
|
||||||
names = []
|
names = []
|
||||||
data = []
|
data = []
|
||||||
|
@ -142,20 +41,11 @@ class Admins::DashboardsController < Admins::BaseController
|
||||||
Time.now.beginning_of_day..Time.now.end_of_day
|
Time.now.beginning_of_day..Time.now.end_of_day
|
||||||
end
|
end
|
||||||
|
|
||||||
def pre_7_days
|
|
||||||
7.days.ago.end_of_day..Time.now.end_of_day
|
|
||||||
end
|
|
||||||
|
|
||||||
def current_week
|
def current_week
|
||||||
Time.now.beginning_of_week..Time.now.end_of_day
|
7.days.ago.beginning_of_day..Time.now.end_of_day
|
||||||
end
|
end
|
||||||
|
|
||||||
def current_month
|
def current_month
|
||||||
30.days.ago.end_of_day..Time.now.end_of_day
|
30.days.ago.beginning_of_day..Time.now.end_of_day
|
||||||
end
|
|
||||||
|
|
||||||
def pre_week
|
|
||||||
# 14.days.ago.end_of_day..7.days.ago.end_of_day
|
|
||||||
Time.now.prev_week..Time.now.prev_week.end_of_week
|
|
||||||
end
|
end
|
||||||
end
|
end
|
|
@ -1,5 +1,4 @@
|
||||||
class Admins::EduSettingsController < Admins::BaseController
|
class Admins::EduSettingsController < Admins::BaseController
|
||||||
before_action :require_admin
|
|
||||||
before_action :find_setting, only: [:edit,:update, :destroy]
|
before_action :find_setting, only: [:edit,:update, :destroy]
|
||||||
|
|
||||||
def index
|
def index
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
class Admins::FaqsController < Admins::BaseController
|
class Admins::FaqsController < Admins::BaseController
|
||||||
before_action :require_business
|
|
||||||
before_action :find_faq, only: [:edit,:update, :destroy]
|
before_action :find_faq, only: [:edit,:update, :destroy]
|
||||||
|
|
||||||
def index
|
def index
|
||||||
|
|
|
@ -1,50 +0,0 @@
|
||||||
class Admins::FeedbacksController < Admins::BaseController
|
|
||||||
before_action :require_business
|
|
||||||
before_action :get_feedback, only: [:new_history, :create_history, :destroy]
|
|
||||||
|
|
||||||
def index
|
|
||||||
sort_by = Feedback.column_names.include?(params[:sort_by]) ? params[:sort_by] : 'created_at'
|
|
||||||
sort_direction = %w(desc asc).include?(params[:sort_direction]) ? params[:sort_direction] : 'desc'
|
|
||||||
feedbacks = Feedback.order("#{sort_by} #{sort_direction}")
|
|
||||||
@feedbacks = paginate(feedbacks)
|
|
||||||
end
|
|
||||||
|
|
||||||
def destroy
|
|
||||||
if @feedback.destroy
|
|
||||||
redirect_to admins_feedbacks_path
|
|
||||||
flash[:success] = "反馈意见删除成功"
|
|
||||||
else
|
|
||||||
redirect_to admins_feedbacks_path
|
|
||||||
flash[:danger] = "反馈意见删除失败"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def new_history
|
|
||||||
@feedback_message_history = FeedbackMessageHistory.new
|
|
||||||
end
|
|
||||||
|
|
||||||
def create_history
|
|
||||||
@feedback_message_history = @feedback.feedback_message_histories.new(feedback_message_history_params)
|
|
||||||
@feedback_message_history.user = current_user
|
|
||||||
if @feedback_message_history.save
|
|
||||||
redirect_to admins_feedbacks_path
|
|
||||||
flash[:success] = "发送通知成功"
|
|
||||||
else
|
|
||||||
redirect_to admins_feedbacks_path
|
|
||||||
flash[:danger] = @feedback_message_history.errors.full_messages.join(", ")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
def feedback_params
|
|
||||||
params.require(:feedback).permit!
|
|
||||||
end
|
|
||||||
|
|
||||||
def feedback_message_history_params
|
|
||||||
params.require(:feedback_message_history).permit(:title, :content)
|
|
||||||
end
|
|
||||||
|
|
||||||
def get_feedback
|
|
||||||
@feedback = Feedback.find_by_id(params[:id])
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,34 +0,0 @@
|
||||||
class Admins::GlccPrCheckController < Admins::BaseController
|
|
||||||
before_action :require_glcc_admin
|
|
||||||
|
|
||||||
def index
|
|
||||||
params[:sort_by] = params[:sort_by].presence || 'created_on'
|
|
||||||
params[:sort_direction] = params[:sort_direction].presence || 'desc'
|
|
||||||
examine_materials = Admins::GlccExamineMaterial.call(params)
|
|
||||||
@examine_materials = paginate examine_materials.includes(:glcc_student)
|
|
||||||
end
|
|
||||||
|
|
||||||
def send_mail
|
|
||||||
year = if params[:date].present?
|
|
||||||
params[:date][:year]
|
|
||||||
end
|
|
||||||
if year.nil?
|
|
||||||
return redirect_to admins_glcc_pr_check_index_path
|
|
||||||
flash[:error] = "时间不能为空"
|
|
||||||
end
|
|
||||||
if params[:term].blank?
|
|
||||||
return redirect_to admins_glcc_pr_check_index_path
|
|
||||||
flash[:error] = "考核选项不能为空"
|
|
||||||
end
|
|
||||||
|
|
||||||
examine_materials = GlccMediumTermExamineMaterial.where(\
|
|
||||||
term: params[:term],
|
|
||||||
created_on: [Time.now.change(year:year).beginning_of_year .. Time.now.change(year:year).end_of_year]
|
|
||||||
)
|
|
||||||
examine_materials.map{ |e|
|
|
||||||
e.send_mail
|
|
||||||
}
|
|
||||||
flash[:danger] = "#{year} 年 #{params[:term].to_i == 1 ? "中期考核": "结项考核"} PR 检测邮件已全部发送完毕,一共#{examine_materials.count}封邮件"
|
|
||||||
redirect_to admins_glcc_pr_check_index_path
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,38 +0,0 @@
|
||||||
class Admins::IdentityVerificationsController < Admins::BaseController
|
|
||||||
before_action :require_business
|
|
||||||
before_action :finder_identity_verification, except: [:index]
|
|
||||||
def index
|
|
||||||
params[:sort_by] = params[:sort_by].presence || 'created_at'
|
|
||||||
params[:sort_direction] = params[:sort_direction].presence || 'desc'
|
|
||||||
identity_verifications = Admins::IdentityVerificationQuery.call(params)
|
|
||||||
@identity_verifications = paginate identity_verifications.preload(:user)
|
|
||||||
end
|
|
||||||
|
|
||||||
def show
|
|
||||||
render 'edit'
|
|
||||||
end
|
|
||||||
def edit
|
|
||||||
end
|
|
||||||
|
|
||||||
def update
|
|
||||||
if update_params[:state] == "已拒绝" && update_params[:description].blank?
|
|
||||||
flash[:danger] = '拒绝理由不能为空'
|
|
||||||
render 'edit'
|
|
||||||
else
|
|
||||||
UserAction.create(action_id: @identity_verification.id, action_type: "UpdateIdentityVerifications", user_id: current_user.id, :ip => request.remote_ip, data_bank: @identity_verification.attributes.to_json)
|
|
||||||
@identity_verification.update(update_params)
|
|
||||||
redirect_to admins_identity_verifications_path
|
|
||||||
flash[:success] = "更新成功"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
def finder_identity_verification
|
|
||||||
@identity_verification = IdentityVerification.find(params[:id])
|
|
||||||
@user = @identity_verification.user
|
|
||||||
end
|
|
||||||
|
|
||||||
def update_params
|
|
||||||
params.require(:identity_verification).permit(:state, :description)
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -2,7 +2,7 @@ class Admins::ImportUsersController < Admins::BaseController
|
||||||
def create
|
def create
|
||||||
return render_error('请上传正确的文件') if params[:file].blank? || !params[:file].is_a?(ActionDispatch::Http::UploadedFile)
|
return render_error('请上传正确的文件') if params[:file].blank? || !params[:file].is_a?(ActionDispatch::Http::UploadedFile)
|
||||||
|
|
||||||
result = Admins::ImportUserFromExcelService.call(params[:file].to_io)
|
result = Admins::ImportUserService.call(params[:file].to_io)
|
||||||
render_ok(result)
|
render_ok(result)
|
||||||
rescue Admins::ImportUserService::Error => ex
|
rescue Admins::ImportUserService::Error => ex
|
||||||
render_error(ex)
|
render_error(ex)
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
class Admins::IssuesRankController < Admins::BaseController
|
|
||||||
before_action :require_admin
|
|
||||||
|
|
||||||
def index
|
|
||||||
@statistics = DailyProjectStatistic.where('date >= ? AND date <= ?', begin_date, end_date)
|
|
||||||
@statistics = @statistics.group(:project_id).joins(:project).select("project_id,
|
|
||||||
sum(issues) as issues,
|
|
||||||
sum(closed_issues) as closed_issues,
|
|
||||||
projects.issues_count as issues_count")
|
|
||||||
@statistics = @statistics.order("#{sort_by} #{sort_direction}").limit(50)
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
def begin_date
|
|
||||||
params.fetch(:begin_date, (Date.yesterday-7.days).to_s)
|
|
||||||
end
|
|
||||||
|
|
||||||
def end_date
|
|
||||||
params.fetch(:end_date, Date.yesterday.to_s)
|
|
||||||
end
|
|
||||||
|
|
||||||
def sort_by
|
|
||||||
DailyProjectStatistic.column_names.include?(params.fetch(:sort_by, "issues")) ? params.fetch(:sort_by, "issues") : "issues"
|
|
||||||
end
|
|
||||||
|
|
||||||
def sort_direction
|
|
||||||
%w(desc asc).include?(params.fetch(:sort_direction, "desc")) ? params.fetch(:sort_direction, "desc") : "desc"
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
|
@ -1,5 +1,4 @@
|
||||||
class Admins::LaboratoriesController < Admins::BaseController
|
class Admins::LaboratoriesController < Admins::BaseController
|
||||||
before_action :require_admin
|
|
||||||
def index
|
def index
|
||||||
default_sort('id', 'desc')
|
default_sort('id', 'desc')
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,6 @@ class Admins::LaboratorySettingsController < Admins::BaseController
|
||||||
params.permit(:identifier, :name,
|
params.permit(:identifier, :name,
|
||||||
:nav_logo, :login_logo, :tab_logo, :oj_banner,
|
:nav_logo, :login_logo, :tab_logo, :oj_banner,
|
||||||
:subject_banner, :course_banner, :competition_banner, :moop_cases_banner,
|
:subject_banner, :course_banner, :competition_banner, :moop_cases_banner,
|
||||||
:footer, navbar: %i[name link hidden index])
|
:footer, navbar: %i[name link hidden])
|
||||||
end
|
end
|
||||||
end
|
end
|
|
@ -1,26 +1,9 @@
|
||||||
class Admins::MessageTemplatesController < Admins::BaseController
|
class Admins::MessageTemplatesController < Admins::BaseController
|
||||||
before_action :require_admin
|
|
||||||
before_action :get_template, only: [:edit, :update, :destroy]
|
before_action :get_template, only: [:edit, :update, :destroy]
|
||||||
|
|
||||||
def index
|
def index
|
||||||
message_templates = MessageTemplate.ransack(sys_notice_or_email_or_email_title_cont: params[:search]).result
|
message_templates = MessageTemplate.group(:type).count.keys
|
||||||
@message_templates = kaminari_paginate(message_templates)
|
@message_templates = kaminari_array_paginate(message_templates)
|
||||||
end
|
|
||||||
|
|
||||||
def new
|
|
||||||
@message_template = MessageTemplate::CustomTip.new
|
|
||||||
end
|
|
||||||
|
|
||||||
def create
|
|
||||||
@message_template = MessageTemplate::CustomTip.new
|
|
||||||
@message_template.attributes = message_template_params
|
|
||||||
if @message_template.save!
|
|
||||||
redirect_to admins_message_templates_path
|
|
||||||
flash[:success] = "创建消息模板成功"
|
|
||||||
else
|
|
||||||
render :new
|
|
||||||
flash[:danger] = "创建消息模板失败"
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def edit
|
def edit
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
class Admins::NpsController < Admins::BaseController
|
|
||||||
before_action :require_business
|
|
||||||
def index
|
|
||||||
@on_off_switch = EduSetting.get("nps-on-off-switch").to_s == 'true'
|
|
||||||
@user_nps = UserNp.joins(:user).order(created_at: :desc)
|
|
||||||
keyword = params[:keyword].to_s.strip.presence
|
|
||||||
if keyword
|
|
||||||
sql = 'CONCAT(users.lastname, users.firstname) LIKE :keyword OR users.nickname LIKE :keyword OR users.login LIKE :keyword OR users.mail LIKE :keyword OR users.phone LIKE :keyword'
|
|
||||||
@user_nps = @user_nps.where(sql, keyword: "%#{keyword}%")
|
|
||||||
end
|
|
||||||
@user_nps = @user_nps.where("action_type != 'close'") if params[:done_score].present?
|
|
||||||
@min_score = @user_nps.where("action_type != 'close'").minimum("score")
|
|
||||||
@max_score = @user_nps.where("action_type != 'close'").maximum("score")
|
|
||||||
@score_total_count = UserNp.where("action_type !='close'").count
|
|
||||||
@user_nps = paginate @user_nps.includes(:user)
|
|
||||||
end
|
|
||||||
|
|
||||||
def switch_change
|
|
||||||
edu_setting = EduSetting.find_by(name: "nps-on-off-switch")
|
|
||||||
if edu_setting.blank?
|
|
||||||
edu_setting = EduSetting.new(name: "nps-on-off-switch")
|
|
||||||
end
|
|
||||||
edu_setting.value = params[:switch].to_s
|
|
||||||
edu_setting.save
|
|
||||||
render_ok
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,45 +0,0 @@
|
||||||
class Admins::OrganizationsController < Admins::BaseController
|
|
||||||
before_action :require_admin
|
|
||||||
before_action :finder_org, except: [:index]
|
|
||||||
|
|
||||||
def index
|
|
||||||
params[:sort_by] = params[:sort_by].presence || 'created_on'
|
|
||||||
params[:sort_direction] = params[:sort_direction].presence || 'desc'
|
|
||||||
|
|
||||||
orgs = Admins::OrganizationQuery.call(params)
|
|
||||||
@orgs = paginate orgs
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
def open_cla
|
|
||||||
@org.open_cla!
|
|
||||||
render_ok
|
|
||||||
end
|
|
||||||
|
|
||||||
def close_cla
|
|
||||||
if @org.cla.nil?
|
|
||||||
@org.close_cla!
|
|
||||||
render_ok
|
|
||||||
else
|
|
||||||
render_error(' 该组织已创建CLA 不允许关闭')
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
def show
|
|
||||||
end
|
|
||||||
|
|
||||||
def destroy
|
|
||||||
@org.destroy!
|
|
||||||
Admins::DeleteOrganizationService.call(@org.login)
|
|
||||||
UserAction.create(action_id: @org.id, action_type: "DestroyOrganization", user_id: current_user.id, :ip => request.remote_ip, data_bank: @org.attributes.to_json)
|
|
||||||
render_delete_success
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def finder_org
|
|
||||||
@org = Organization.find(params[:id])
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
|
@ -1,80 +0,0 @@
|
||||||
class Admins::PageThemesController < Admins::BaseController
|
|
||||||
before_action :require_admin
|
|
||||||
before_action :finder_page_theme, only: [:edit, :update, :destroy]
|
|
||||||
|
|
||||||
def index
|
|
||||||
params[:sort_by] = params[:sort_by].presence || 'created_at'
|
|
||||||
params[:sort_direction] = params[:sort_direction].presence || 'desc'
|
|
||||||
|
|
||||||
page_themes = Admins::PageThemesQuery.call(params)
|
|
||||||
|
|
||||||
@page_themes = paginate page_themes
|
|
||||||
end
|
|
||||||
|
|
||||||
def show
|
|
||||||
render 'edit'
|
|
||||||
end
|
|
||||||
|
|
||||||
def edit
|
|
||||||
end
|
|
||||||
|
|
||||||
def create
|
|
||||||
@page_theme = PageTheme.new theme_params
|
|
||||||
if @page_theme.save
|
|
||||||
save_image_file(params[:image])
|
|
||||||
redirect_to admins_page_themes_path
|
|
||||||
flash[:success] = "新增主题成功"
|
|
||||||
else
|
|
||||||
redirect_to admins_page_themes_path
|
|
||||||
flash[:danger] = "新增主题失败: #{@page_theme.errors.messages.values.flatten.join(',')}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def destroy
|
|
||||||
if PageTheme.where(language_frame: @page_theme.language_frame).count <= 1
|
|
||||||
flash[:danger] = "删除主题失败,必须存在一个主题"
|
|
||||||
return redirect_to admins_page_themes_path
|
|
||||||
end
|
|
||||||
|
|
||||||
if @page_theme.destroy
|
|
||||||
redirect_to admins_page_themes_path
|
|
||||||
flash[:success] = "删除主题成功"
|
|
||||||
else
|
|
||||||
redirect_to admins_page_themes_path
|
|
||||||
flash[:danger] = "删除主题失败"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def new
|
|
||||||
@page_theme = PageTheme.new
|
|
||||||
end
|
|
||||||
|
|
||||||
def update
|
|
||||||
@page_theme.attributes = theme_params
|
|
||||||
if @page_theme.save
|
|
||||||
save_image_file(params[:image])
|
|
||||||
redirect_to admins_page_themes_path
|
|
||||||
flash[:success] = "更新成功"
|
|
||||||
else
|
|
||||||
redirect_to admins_page_themes_path
|
|
||||||
flash[:danger] = "更新失败"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
def finder_page_theme
|
|
||||||
@page_theme = PageTheme.find(params[:id])
|
|
||||||
end
|
|
||||||
|
|
||||||
def theme_params
|
|
||||||
params.require(:page_theme).permit(:language_frame, :name, :cate, :image_url, :clone_url, :order_index)
|
|
||||||
end
|
|
||||||
|
|
||||||
def save_image_file(file)
|
|
||||||
return unless file.present? && file.is_a?(ActionDispatch::Http::UploadedFile)
|
|
||||||
file_path = Util::FileManage.source_disk_filename(@page_theme, "image")
|
|
||||||
File.delete(file_path) if File.exist?(file_path) # 删除之前的文件
|
|
||||||
Util.write_file(file, file_path)
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
|
@ -1,5 +1,4 @@
|
||||||
class Admins::ProjectCategoriesController < Admins::BaseController
|
class Admins::ProjectCategoriesController < Admins::BaseController
|
||||||
before_action :require_admin
|
|
||||||
before_action :get_category, only: [:edit,:update, :destroy]
|
before_action :get_category, only: [:edit,:update, :destroy]
|
||||||
before_action :validate_names, only: [:create, :update]
|
before_action :validate_names, only: [:create, :update]
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
class Admins::ProjectIgnoresController < Admins::BaseController
|
class Admins::ProjectIgnoresController < Admins::BaseController
|
||||||
before_action :require_admin
|
|
||||||
before_action :set_ignore, only: [:edit,:update, :destroy,:show]
|
before_action :set_ignore, only: [:edit,:update, :destroy,:show]
|
||||||
# before_action :validate_params, only: [:create, :update]
|
before_action :validate_params, only: [:create, :update]
|
||||||
|
|
||||||
def index
|
def index
|
||||||
sort_by = Ignore.column_names.include?(params[:sort_by]) ? params[:sort_by] : 'created_at'
|
sort_by = Ignore.column_names.include?(params[:sort_by]) ? params[:sort_by] : 'created_at'
|
||||||
|
@ -32,12 +31,12 @@ class Admins::ProjectIgnoresController < Admins::BaseController
|
||||||
# }
|
# }
|
||||||
@project_ignore = Ignore.new(ignore_params)
|
@project_ignore = Ignore.new(ignore_params)
|
||||||
|
|
||||||
if @project_ignore.save
|
if @project_ignore.save!
|
||||||
redirect_to admins_project_ignores_path
|
redirect_to admins_project_ignores_path
|
||||||
flash[:success] = "创建成功"
|
flash[:success] = "创建成功"
|
||||||
else
|
else
|
||||||
redirect_to admins_project_ignores_path
|
render :new
|
||||||
flash[:danger] = @project_ignore.errors.full_messages.join(",")
|
flash[:danger] = "创建失败"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -59,8 +58,8 @@ class Admins::ProjectIgnoresController < Admins::BaseController
|
||||||
redirect_to admins_project_ignores_path
|
redirect_to admins_project_ignores_path
|
||||||
flash[:success] = "更新成功"
|
flash[:success] = "更新成功"
|
||||||
else
|
else
|
||||||
redirect_to admins_project_ignores_path
|
render :edit
|
||||||
flash[:danger] = @project_ignore.errors.full_messages.join(",")
|
flash[:danger] = "更新失败"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -99,23 +98,23 @@ class Admins::ProjectIgnoresController < Admins::BaseController
|
||||||
params.require(:ignore).permit(:name,:content)
|
params.require(:ignore).permit(:name,:content)
|
||||||
end
|
end
|
||||||
|
|
||||||
# def validate_params
|
def validate_params
|
||||||
# name = params[:ignore][:name]
|
name = params[:ignore][:name]
|
||||||
# if name.blank?
|
if name.blank?
|
||||||
# flash[:danger] = "名称不允许为空"
|
flash[:danger] = "名称不允许为空"
|
||||||
# redirect_to admins_project_ignores_path
|
redirect_to admins_project_ignores_path
|
||||||
# elsif check_ignore_present?(name) && @project_ignore.blank?
|
elsif check_ignore_present?(name) && @project_ignore.blank?
|
||||||
# flash[:danger] = "创建失败:名称已存在"
|
flash[:danger] = "创建失败:名称已存在"
|
||||||
# redirect_to admins_project_ignores_path
|
redirect_to admins_project_ignores_path
|
||||||
# end
|
end
|
||||||
# end
|
end
|
||||||
|
|
||||||
# def check_ignore_present?(name)
|
def check_ignore_present?(name)
|
||||||
# return true if name.blank?
|
return true if name.blank?
|
||||||
# name_downcase = name.downcase
|
name_downcase = name.downcase
|
||||||
# name_upcase = name.upcase
|
name_upcase = name.upcase
|
||||||
# name_first_big = name.capitalize
|
name_first_big = name.capitalize
|
||||||
# Ignore.exists?(name: name_downcase) || Ignore.exists?(name: name_upcase) || Ignore.exists?(name: name_first_big)
|
Ignore.exists?(name: name_downcase) || Ignore.exists?(name: name_upcase) || Ignore.exists?(name: name_first_big)
|
||||||
# end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
class Admins::ProjectLanguagesController < Admins::BaseController
|
class Admins::ProjectLanguagesController < Admins::BaseController
|
||||||
before_action :require_admin
|
|
||||||
before_action :get_language, only: [:edit,:update, :destroy]
|
before_action :get_language, only: [:edit,:update, :destroy]
|
||||||
before_action :validate_names, only: [:create, :update]
|
before_action :validate_names, only: [:create, :update]
|
||||||
|
|
||||||
|
@ -28,18 +27,17 @@ class Admins::ProjectLanguagesController < Admins::BaseController
|
||||||
flash[:success] = '创建成功'
|
flash[:success] = '创建成功'
|
||||||
else
|
else
|
||||||
redirect_to admins_project_languages_path
|
redirect_to admins_project_languages_path
|
||||||
flash[:danger] = @project_language.errors.full_messages.join(",")
|
flash[:danger] = '创建失败'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
@project_language.attributes = {name: @name}
|
if @project_language.update_attribute(:name, @name)
|
||||||
if @project_language.save
|
|
||||||
redirect_to admins_project_languages_path
|
redirect_to admins_project_languages_path
|
||||||
flash[:success] = '更新成功'
|
flash[:success] = '更新成功'
|
||||||
else
|
else
|
||||||
redirect_to admins_project_languages_path
|
redirect_to admins_project_languages_path
|
||||||
flash[:danger] = @project_language.errors.full_messages.join(",")
|
flash[:success] = '更新失败'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
class Admins::ProjectLicensesController < Admins::BaseController
|
class Admins::ProjectLicensesController < Admins::BaseController
|
||||||
before_action :require_admin
|
|
||||||
before_action :set_license, only: [:edit,:update, :destroy,:show]
|
before_action :set_license, only: [:edit,:update, :destroy,:show]
|
||||||
# before_action :validate_params, only: [:create, :update]
|
before_action :validate_params, only: [:create, :update]
|
||||||
|
|
||||||
def index
|
def index
|
||||||
sort_by = License.column_names.include?(params[:sort_by]) ? params[:sort_by] : 'created_at'
|
sort_by = License.column_names.include?(params[:sort_by]) ? params[:sort_by] : 'created_at'
|
||||||
sort_direction = %w(desc asc).include?(params[:sort_direction]) ? params[:sort_direction] : 'desc'
|
sort_direction = %w(desc asc).include?(params[:sort_direction]) ? params[:sort_direction] : 'desc'
|
||||||
q = License.ransack(name_cont: params[:search])
|
q = License.ransack(name_cont: params[:search])
|
||||||
project_licenses = q.result(distinct: true).reorder("#{sort_by} #{sort_direction}")
|
project_licenses = q.result(distinct: true).order("#{sort_by} #{sort_direction}")
|
||||||
@project_licenses = paginate(project_licenses)
|
@project_licenses = paginate(project_licenses)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -31,12 +30,13 @@ class Admins::ProjectLicensesController < Admins::BaseController
|
||||||
# position: max_position
|
# position: max_position
|
||||||
# }
|
# }
|
||||||
@project_license = License.new(license_params)
|
@project_license = License.new(license_params)
|
||||||
if @project_license.save
|
|
||||||
|
if @project_license.save!
|
||||||
redirect_to admins_project_licenses_path
|
redirect_to admins_project_licenses_path
|
||||||
flash[:success] = "创建成功"
|
flash[:success] = "创建成功"
|
||||||
else
|
else
|
||||||
redirect_to admins_project_licenses_path
|
render :new
|
||||||
flash[:danger] = @project_license.errors.full_messages.join(",")
|
flash[:danger] = "创建失败"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -54,13 +54,12 @@ class Admins::ProjectLicensesController < Admins::BaseController
|
||||||
# permissions: permissions.to_s,
|
# permissions: permissions.to_s,
|
||||||
# limitations: limitations.to_s
|
# limitations: limitations.to_s
|
||||||
# }
|
# }
|
||||||
@project_license.attributes = license_params
|
if @project_license.update_attributes(license_params)
|
||||||
if @project_license.save
|
|
||||||
redirect_to admins_project_licenses_path
|
redirect_to admins_project_licenses_path
|
||||||
flash[:success] = "更新成功"
|
flash[:success] = "更新成功"
|
||||||
else
|
else
|
||||||
render admins_project_licenses_path
|
render :edit
|
||||||
flash[:danger] = @project_license.errors.full_messages.join(",")
|
flash[:danger] = "更新失败"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -96,26 +95,26 @@ class Admins::ProjectLicensesController < Admins::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def license_params
|
def license_params
|
||||||
params.require(:license).permit(:name,:content,:position)
|
params.require(:license).permit(:name,:content)
|
||||||
end
|
end
|
||||||
|
|
||||||
# def validate_params
|
def validate_params
|
||||||
# name = params[:license][:name]
|
name = params[:license][:name]
|
||||||
# if name.blank?
|
if name.blank?
|
||||||
# flash[:danger] = "名称不允许为空"
|
flash[:danger] = "名称不允许为空"
|
||||||
# redirect_to admins_project_licenses_path
|
redirect_to admins_project_licenses_path
|
||||||
# elsif check_license_present?(name) && @project_license.blank?
|
elsif check_license_present?(name) && @project_license.blank?
|
||||||
# flash[:danger] = "创建失败:名称已存在"
|
flash[:danger] = "创建失败:名称已存在"
|
||||||
# redirect_to admins_project_licenses_path
|
redirect_to admins_project_licenses_path
|
||||||
# end
|
end
|
||||||
# end
|
end
|
||||||
|
|
||||||
# def check_license_present?(name)
|
def check_license_present?(name)
|
||||||
# return true if name.blank?
|
return true if name.blank?
|
||||||
# name_downcase = name.downcase
|
name_downcase = name.downcase
|
||||||
# name_upcase = name.upcase
|
name_upcase = name.upcase
|
||||||
# name_first_big = name.capitalize
|
name_first_big = name.capitalize
|
||||||
# License.exists?(name: name_downcase) || License.exists?(name: name_upcase) || License.exists?(name: name_first_big)
|
License.exists?(name: name_downcase) || License.exists?(name: name_upcase) || License.exists?(name: name_first_big)
|
||||||
# end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,22 +1,11 @@
|
||||||
class Admins::ProjectsController < Admins::BaseController
|
class Admins::ProjectsController < Admins::BaseController
|
||||||
before_action :require_admin
|
|
||||||
before_action :find_project, only: [:edit, :update]
|
before_action :find_project, only: [:edit, :update]
|
||||||
|
|
||||||
def index
|
def index
|
||||||
sort_by = Project.column_names.include?(params[:sort_by]) ? params[:sort_by] : 'created_on'
|
sort_by = Project.column_names.include?(params[:sort_by]) ? params[:sort_by] : 'created_on'
|
||||||
sort_direction = %w(desc asc).include?(params[:sort_direction]) ? params[:sort_direction] : 'desc'
|
sort_direction = %w(desc asc).include?(params[:sort_direction]) ? params[:sort_direction] : 'desc'
|
||||||
search = params[:search].to_s.strip
|
search = params[:search].to_s.strip
|
||||||
projects = Project.where("name like ? OR identifier LIKE ?", "%#{search}%", "%#{search}%").order("#{sort_by} #{sort_direction}")
|
projects = Project.where("name like ?", "%#{search}%").order("#{sort_by} #{sort_direction}")
|
||||||
case params[:category]
|
|
||||||
when 'public'
|
|
||||||
projects = projects.where(is_public: true)
|
|
||||||
when 'private'
|
|
||||||
projects = projects.where(is_public: false)
|
|
||||||
when 'fork'
|
|
||||||
projects = projects.where.not(forked_from_project_id: nil)
|
|
||||||
when 'original'
|
|
||||||
projects = projects.where(forked_from_project_id: nil, project_type: 'common')
|
|
||||||
end
|
|
||||||
@projects = paginate projects.includes(:owner, :members, :issues, :versions, :attachments, :project_score)
|
@projects = paginate projects.includes(:owner, :members, :issues, :versions, :attachments, :project_score)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -43,14 +32,9 @@ class Admins::ProjectsController < Admins::BaseController
|
||||||
def destroy
|
def destroy
|
||||||
project = Project.find_by!(id: params[:id])
|
project = Project.find_by!(id: params[:id])
|
||||||
ActiveRecord::Base.transaction do
|
ActiveRecord::Base.transaction do
|
||||||
close_fork_pull_requests_by(project)
|
Gitea::Repository::DeleteService.new(project.owner, project.identifier).call
|
||||||
Gitea::Repository::DeleteService.new(project.owner, project.identifier, current_user.gitea_token).call
|
|
||||||
project.destroy!
|
project.destroy!
|
||||||
project.forked_projects.update_all(forked_from_project_id: nil)
|
|
||||||
# 如果该项目有所属的项目分类以及为私有项目,需要更新对应数量
|
|
||||||
project.project_category.decrement!(:private_projects_count, 1) if project.project_category.present? && !project.is_public
|
|
||||||
# render_delete_success
|
# render_delete_success
|
||||||
UserAction.create(action_id: project.id, action_type: "DestroyProject", user_id: current_user.id, :ip => request.remote_ip, data_bank: project.attributes.to_json)
|
|
||||||
redirect_to admins_projects_path
|
redirect_to admins_projects_path
|
||||||
flash[:success] = "删除成功"
|
flash[:success] = "删除成功"
|
||||||
end
|
end
|
||||||
|
@ -67,19 +51,4 @@ class Admins::ProjectsController < Admins::BaseController
|
||||||
def project_update_params
|
def project_update_params
|
||||||
params.require(:project).permit(:is_pinned, :recommend, :recommend_index)
|
params.require(:project).permit(:is_pinned, :recommend, :recommend_index)
|
||||||
end
|
end
|
||||||
|
|
||||||
def close_fork_pull_requests_by(project)
|
|
||||||
open_pull_requests = PullRequest.where(fork_project_id: project.id)
|
|
||||||
if open_pull_requests.present?
|
|
||||||
open_pull_requests.each do |pull_request|
|
|
||||||
closed = PullRequests::CloseService.call(pull_request&.project.owner, pull_request&.project.repository, pull_request, current_user)
|
|
||||||
if closed === true
|
|
||||||
pull_request.project_trends.create!(user: current_user, project: pull_request&.project,action_type: ProjectTrend::CLOSE)
|
|
||||||
# 合并请求下issue处理为关闭
|
|
||||||
pull_request.issue&.update_attributes!({status_id:5})
|
|
||||||
SendTemplateMessageJob.perform_later('PullRequestClosed', current_user.id, pull_request.id) if Site.has_notice_menu?
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
|
@ -1,57 +0,0 @@
|
||||||
class Admins::ProjectsRankController < Admins::BaseController
|
|
||||||
before_action :require_admin
|
|
||||||
|
|
||||||
def index
|
|
||||||
@statistics = DailyProjectStatistic.where("date >= ? AND date <= ?", begin_date, end_date)
|
|
||||||
@statistics = @statistics.group(:project_id).select("project_id,
|
|
||||||
sum(score) as score,
|
|
||||||
sum(visits) as visits,
|
|
||||||
sum(watchers) as watchers,
|
|
||||||
sum(praises) as praises,
|
|
||||||
sum(forks) as forks,
|
|
||||||
sum(issues) as issues,
|
|
||||||
sum(pullrequests) as pullrequests,
|
|
||||||
sum(commits) as commits").includes(:project)
|
|
||||||
@statistics = paginate @statistics.order("#{sort_by} #{sort_direction}")
|
|
||||||
export_excel(@statistics.limit(50))
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def begin_date
|
|
||||||
params.fetch(:begin_date, (Date.yesterday-7.days).to_s)
|
|
||||||
end
|
|
||||||
|
|
||||||
def end_date
|
|
||||||
params.fetch(:end_date, Date.yesterday.to_s)
|
|
||||||
end
|
|
||||||
|
|
||||||
def sort_by
|
|
||||||
DailyProjectStatistic.column_names.include?(params.fetch(:sort_by, "score")) ? params.fetch(:sort_by, "score") : "score"
|
|
||||||
end
|
|
||||||
|
|
||||||
def sort_direction
|
|
||||||
%w(desc asc).include?(params.fetch(:sort_direction, "desc")) ? params.fetch(:sort_direction, "desc") : "desc"
|
|
||||||
end
|
|
||||||
|
|
||||||
def export_excel(data)
|
|
||||||
book = Spreadsheet::Workbook.new
|
|
||||||
sheet = book.create_worksheet :name => "项目活跃度排行"
|
|
||||||
sheet.row(0).concat %w(排名 项目全称 项目地址 得分 访问数 关注数 点赞数 fork数 疑修数 合并请求数 提交数)
|
|
||||||
data.each_with_index do |d, index|
|
|
||||||
sheet[index+1,0] = index+1
|
|
||||||
sheet[index+1,1] = "#{d&.project&.owner&.real_name}/#{d&.project&.name}"
|
|
||||||
sheet[index+1,2] = "#{Rails.application.config_for(:configuration)['platform_url']}/#{d&.project&.owner&.login}/#{d&.project&.identifier}"
|
|
||||||
sheet[index+1,3] = d.score
|
|
||||||
sheet[index+1,4] = d.visits
|
|
||||||
sheet[index+1,5] = d.watchers
|
|
||||||
sheet[index+1,6] = d.praises
|
|
||||||
sheet[index+1,7] = d.forks
|
|
||||||
sheet[index+1,8] = d.issues
|
|
||||||
sheet[index+1,9] = d.pullrequests
|
|
||||||
sheet[index+1,10] = d.commits
|
|
||||||
end
|
|
||||||
book.write "#{Rails.root}/public/项目活跃度排行.xls"
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
|
@ -1,5 +1,4 @@
|
||||||
class Admins::ReversedKeywordsController < Admins::BaseController
|
class Admins::ReversedKeywordsController < Admins::BaseController
|
||||||
before_action :require_admin
|
|
||||||
before_action :get_keyword, only: [:edit,:update, :destroy]
|
before_action :get_keyword, only: [:edit,:update, :destroy]
|
||||||
# before_action :validate_identifer, only: [:create, :update]
|
# before_action :validate_identifer, only: [:create, :update]
|
||||||
|
|
||||||
|
|
|
@ -1,51 +0,0 @@
|
||||||
class Admins::SitePagesController < Admins::BaseController
|
|
||||||
before_action :require_admin
|
|
||||||
before_action :finder_site_page, except: [:index]
|
|
||||||
|
|
||||||
def index
|
|
||||||
params[:sort_by] = params[:sort_by].presence || 'created_at'
|
|
||||||
params[:sort_direction] = params[:sort_direction].presence || 'desc'
|
|
||||||
|
|
||||||
pages = Admins::SitePagesQuery.call(params)
|
|
||||||
|
|
||||||
@site_pages = paginate pages.preload(:user)
|
|
||||||
end
|
|
||||||
|
|
||||||
def show
|
|
||||||
render 'edit'
|
|
||||||
end
|
|
||||||
|
|
||||||
def edit
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
def destroy
|
|
||||||
if @site_page.destroy
|
|
||||||
redirect_to admins_site_pages_path
|
|
||||||
flash[:success] = "删除站点成功"
|
|
||||||
else
|
|
||||||
redirect_to admins_site_pages_path
|
|
||||||
flash[:danger] = "删除站点失败"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def update
|
|
||||||
if update_params[:state] == "false" && update_params[:state_description].blank?
|
|
||||||
flash[:danger] = '关闭站点理由不能为空'
|
|
||||||
else
|
|
||||||
@site_page.update(update_params)
|
|
||||||
flash[:success] = '保存成功'
|
|
||||||
end
|
|
||||||
render 'edit'
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
def finder_site_page
|
|
||||||
@site_page = Page.find(params[:id])
|
|
||||||
@user = @site_page.user
|
|
||||||
end
|
|
||||||
|
|
||||||
def update_params
|
|
||||||
params.require(:page).permit(:state, :state_description)
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,5 +1,4 @@
|
||||||
class Admins::SitesController < Admins::BaseController
|
class Admins::SitesController < Admins::BaseController
|
||||||
before_action :require_admin
|
|
||||||
before_action :find_site, only: [:edit,:update, :destroy]
|
before_action :find_site, only: [:edit,:update, :destroy]
|
||||||
|
|
||||||
def index
|
def index
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
class Admins::SystemNotificationsController < Admins::BaseController
|
class Admins::SystemNotificationsController < Admins::BaseController
|
||||||
before_action :require_business
|
|
||||||
before_action :get_notification, only: [:history, :edit,:update, :destroy]
|
before_action :get_notification, only: [:history, :edit,:update, :destroy]
|
||||||
# before_action :validate_identifer, only: [:create, :update]
|
# before_action :validate_identifer, only: [:create, :update]
|
||||||
|
|
||||||
|
@ -26,7 +25,7 @@ class Admins::SystemNotificationsController < Admins::BaseController
|
||||||
@notification = SystemNotification.new(notification_params)
|
@notification = SystemNotification.new(notification_params)
|
||||||
if @notification.save
|
if @notification.save
|
||||||
redirect_to admins_system_notifications_path
|
redirect_to admins_system_notifications_path
|
||||||
flash[:success] = '系统公告创建成功'
|
flash[:success] = '系统消息创建成功'
|
||||||
else
|
else
|
||||||
redirect_to admins_system_notifications_path
|
redirect_to admins_system_notifications_path
|
||||||
flash[:danger] = @notification.errors.full_messages.join(",")
|
flash[:danger] = @notification.errors.full_messages.join(",")
|
||||||
|
@ -38,7 +37,7 @@ class Admins::SystemNotificationsController < Admins::BaseController
|
||||||
if @notification.update_attributes(notification_params)
|
if @notification.update_attributes(notification_params)
|
||||||
format.html do
|
format.html do
|
||||||
redirect_to admins_system_notifications_path
|
redirect_to admins_system_notifications_path
|
||||||
flash[:success] = '系统公告更新成功'
|
flash[:success] = '系统消息更新成功'
|
||||||
end
|
end
|
||||||
format.js {render_ok}
|
format.js {render_ok}
|
||||||
else
|
else
|
||||||
|
@ -54,10 +53,10 @@ class Admins::SystemNotificationsController < Admins::BaseController
|
||||||
def destroy
|
def destroy
|
||||||
if @notification.destroy
|
if @notification.destroy
|
||||||
redirect_to admins_system_notifications_path
|
redirect_to admins_system_notifications_path
|
||||||
flash[:success] = "系统公告删除成功"
|
flash[:success] = "系统消息删除成功"
|
||||||
else
|
else
|
||||||
redirect_to admins_system_notifications_path
|
redirect_to admins_system_notifications_path
|
||||||
flash[:danger] = "系统公告删除失败"
|
flash[:danger] = "系统消息删除失败"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
class Admins::Topic::ActivityForumsController < Admins::Topic::BaseController
|
class Admins::Topic::ActivityForumsController < Admins::Topic::BaseController
|
||||||
before_action :require_business
|
|
||||||
before_action :find_activity_forum, only: [:edit, :update, :destroy]
|
before_action :find_activity_forum, only: [:edit, :update, :destroy]
|
||||||
|
|
||||||
def index
|
def index
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
class Admins::Topic::BannersController < Admins::Topic::BaseController
|
class Admins::Topic::BannersController < Admins::Topic::BaseController
|
||||||
before_action :require_business
|
|
||||||
before_action :find_banner, only: [:edit, :update, :destroy]
|
before_action :find_banner, only: [:edit, :update, :destroy]
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@banners = paginate(::Topic::Banner)
|
@banners = paginate(::Topic::Banner)
|
||||||
@banners = paginate(::Topic::Banner.where("title like ?", "%#{params[:search]}%")) if params[:search].present?
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def new
|
def new
|
||||||
|
@ -54,6 +52,6 @@ class Admins::Topic::BannersController < Admins::Topic::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def banner_params
|
def banner_params
|
||||||
params.require(:topic_banner).permit(:title, :order_index, :url)
|
params.require(:topic_banner).permit(:title, :order_index)
|
||||||
end
|
end
|
||||||
end
|
end
|
|
@ -1,5 +1,4 @@
|
||||||
class Admins::Topic::CardsController < Admins::Topic::BaseController
|
class Admins::Topic::CardsController < Admins::Topic::BaseController
|
||||||
before_action :require_business
|
|
||||||
before_action :find_card, only: [:edit, :update, :destroy]
|
before_action :find_card, only: [:edit, :update, :destroy]
|
||||||
|
|
||||||
def index
|
def index
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
class Admins::Topic::CooperatorsController < Admins::Topic::BaseController
|
class Admins::Topic::CooperatorsController < Admins::Topic::BaseController
|
||||||
before_action :require_business
|
|
||||||
before_action :find_cooperator, only: [:edit, :update, :destroy]
|
before_action :find_cooperator, only: [:edit, :update, :destroy]
|
||||||
|
|
||||||
def index
|
def index
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
class Admins::Topic::ExcellentProjectsController < Admins::Topic::BaseController
|
class Admins::Topic::ExcellentProjectsController < Admins::Topic::BaseController
|
||||||
before_action :require_business
|
|
||||||
before_action :find_excellent_project, only: [:edit, :update, :destroy]
|
before_action :find_excellent_project, only: [:edit, :update, :destroy]
|
||||||
|
|
||||||
def index
|
def index
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
class Admins::Topic::ExperienceForumsController < Admins::Topic::BaseController
|
class Admins::Topic::ExperienceForumsController < Admins::Topic::BaseController
|
||||||
before_action :require_business
|
|
||||||
before_action :find_experience_forum, only: [:edit, :update, :destroy]
|
before_action :find_experience_forum, only: [:edit, :update, :destroy]
|
||||||
|
|
||||||
def index
|
def index
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
class Admins::Topic::GlccNewsController < Admins::Topic::BaseController
|
class Admins::Topic::GlccNewsController < Admins::Topic::BaseController
|
||||||
before_action :require_glcc_admin
|
|
||||||
before_action :find_glcc, only: [:edit, :update, :destroy]
|
before_action :find_glcc, only: [:edit, :update, :destroy]
|
||||||
|
|
||||||
def index
|
def index
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
class Admins::Topic::PinnedForumsController < Admins::Topic::BaseController
|
class Admins::Topic::PinnedForumsController < Admins::Topic::BaseController
|
||||||
before_action :require_business
|
|
||||||
before_action :find_pinned_forum, only: [:edit, :update, :destroy]
|
before_action :find_pinned_forum, only: [:edit, :update, :destroy]
|
||||||
|
|
||||||
def index
|
def index
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
class Admins::UsersController < Admins::BaseController
|
class Admins::UsersController < Admins::BaseController
|
||||||
before_action :require_admin
|
before_action :finder_user, except: [:index]
|
||||||
before_action :finder_user, except: [:index]
|
|
||||||
|
|
||||||
def index
|
def index
|
||||||
params[:sort_by] = params[:sort_by].presence || 'created_on'
|
params[:sort_by] = params[:sort_by].presence || 'created_on'
|
||||||
|
@ -26,16 +25,15 @@ class Admins::UsersController < Admins::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
UserAction.create(action_id: @user.id, action_type: "DestroyUser", user_id: current_user.id, :ip => request.remote_ip, data_bank: @user.attributes.to_json)
|
|
||||||
@user.destroy!
|
@user.destroy!
|
||||||
Gitea::User::DeleteService.call(@user.login)
|
Gitea::User::DeleteService.call(@user.login)
|
||||||
|
|
||||||
render_delete_success
|
render_delete_success
|
||||||
end
|
end
|
||||||
|
|
||||||
def lock
|
def lock
|
||||||
@user.lock!
|
@user.lock!
|
||||||
UserAction.create(action_id: @user.id, action_type: "LockUser", user_id: current_user.id, :ip => request.remote_ip)
|
|
||||||
render_ok
|
render_ok
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -59,12 +57,6 @@ class Admins::UsersController < Admins::BaseController
|
||||||
render_ok
|
render_ok
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
def fresh_gitea_token
|
|
||||||
@user.fresh_gitea_token
|
|
||||||
render_ok
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def finder_user
|
def finder_user
|
||||||
|
@ -72,8 +64,8 @@ class Admins::UsersController < Admins::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_params
|
def update_params
|
||||||
params.require(:user).permit(%i[lastname nickname gender technical_title is_shixun_marker
|
params.require(:user).permit(%i[lastname nickname gender identity technical_title student_id is_shixun_marker
|
||||||
mail phone location location_city school_id department_id admin
|
mail phone location location_city school_id department_id admin business is_test
|
||||||
password login website_permission business glcc_admin])
|
password professional_certification authentication login])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
class Admins::UsersRankController < Admins::BaseController
|
|
||||||
before_action :require_admin
|
|
||||||
|
|
||||||
def index
|
|
||||||
@rank_date = rank_date
|
|
||||||
@date_rank = $redis_cache.zrevrange("v2-user-rank-#{rank_date}", 0, -1, withscores: true)
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def rank_date
|
|
||||||
params.fetch(:date, Date.today.to_s)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
end
|
|
|
@ -1,68 +0,0 @@
|
||||||
class Api::V1::BaseController < ApplicationController
|
|
||||||
|
|
||||||
include Api::ProjectHelper
|
|
||||||
include Api::UserHelper
|
|
||||||
include Api::PullHelper
|
|
||||||
|
|
||||||
# before_action :doorkeeper_authorize!
|
|
||||||
# skip_before_action :user_setup
|
|
||||||
|
|
||||||
protected
|
|
||||||
# def current_user
|
|
||||||
# #client方法对接,需要一直带着用户标识uid
|
|
||||||
# Rails.logger.info doorkeeper_token
|
|
||||||
# if doorkeeper_token && doorkeeper_token.resource_owner_id.blank?
|
|
||||||
# # return User.anonymous if params[:uid].nil?
|
|
||||||
# # tip_exception("2222")
|
|
||||||
# # return render_error('缺少用户标识!') if params[:uid].nil?
|
|
||||||
# User.current = User.find(params[:uid])
|
|
||||||
# else
|
|
||||||
# User.find(doorkeeper_token.resource_owner_id) if doorkeeper_token
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
|
|
||||||
def kaminary_select_paginate(relation)
|
|
||||||
limit = params[:limit] || params[:per_page]
|
|
||||||
limit = (limit.to_i.zero? || limit.to_i > 200) ? 200 : limit.to_i
|
|
||||||
page = params[:page].to_i.zero? ? 1 : params[:page].to_i
|
|
||||||
|
|
||||||
relation.page(page).per(limit)
|
|
||||||
end
|
|
||||||
|
|
||||||
def limit
|
|
||||||
params.fetch(:limit, 15)
|
|
||||||
end
|
|
||||||
|
|
||||||
def page
|
|
||||||
params.fetch(:page, 1)
|
|
||||||
end
|
|
||||||
|
|
||||||
# 具有对仓库的管理权限
|
|
||||||
def require_manager_above
|
|
||||||
@project = load_project
|
|
||||||
return render_forbidden if !current_user.admin? && !@project.manager?(current_user)
|
|
||||||
end
|
|
||||||
|
|
||||||
# 具有对仓库的操作权限
|
|
||||||
def require_operate_above
|
|
||||||
@project = load_project
|
|
||||||
return render_forbidden if !current_user.admin? && !@project.operator?(current_user)
|
|
||||||
end
|
|
||||||
|
|
||||||
# 具有仓库的操作权限或者fork仓库的操作权限
|
|
||||||
def require_operate_above_or_fork_project
|
|
||||||
@project = load_project
|
|
||||||
return render_forbidden if !current_user.admin? && !@project.operator?(current_user) && !(@project.fork_project.present? && @project.fork_project.operator?(current_user))
|
|
||||||
end
|
|
||||||
|
|
||||||
def require_member_above
|
|
||||||
@project = load_project
|
|
||||||
return render_forbidden if !current_user.admin? && !@project.member?(current_user)
|
|
||||||
end
|
|
||||||
|
|
||||||
# 具有对仓库的访问权限
|
|
||||||
def require_public_and_member_above
|
|
||||||
@project = load_project
|
|
||||||
return render_forbidden if !@project.is_public && !current_user.admin? && !@project.member?(current_user)
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,37 +0,0 @@
|
||||||
class Api::V1::GitlinkCompetitionAppliesController < Api::V1::BaseController
|
|
||||||
|
|
||||||
def create
|
|
||||||
return render_error("请输入正确的竞赛ID") unless params[:competition_id].present?
|
|
||||||
return render_error("请输入正确的队伍ID") unless params[:team_id].present?
|
|
||||||
return render_error("请输入正确的队伍成员信息") unless params[:team_members].is_a?(Array)
|
|
||||||
params[:team_members].each do |member|
|
|
||||||
apply = GitlinkCompetitionApply.find_or_create_by(competition_id: params[:competition_id], team_id: params[:team_id], educoder_login: member[:login])
|
|
||||||
apply.competition_identifier = params[:competition_identifier]
|
|
||||||
apply.team_name = params[:team_name]
|
|
||||||
apply.school_name = member[:school_name]
|
|
||||||
apply.nickname = member[:nickname]
|
|
||||||
apply.identity = member[:identity]
|
|
||||||
apply.role = member[:role]
|
|
||||||
apply.email = member[:email]
|
|
||||||
user_info = get_user_info_by_educoder_login(member[:login])
|
|
||||||
apply.phone = user_info["phone"]
|
|
||||||
apply.save
|
|
||||||
end
|
|
||||||
render_ok
|
|
||||||
end
|
|
||||||
|
|
||||||
def get_user_info_by_educoder_login(edu_login)
|
|
||||||
req_params = { "login" => "#{edu_login}", "private_token" => "hriEn3UwXfJs3PmyXnqQ" }
|
|
||||||
api_url= "https://data.educoder.net"
|
|
||||||
client = Faraday.new(url: api_url)
|
|
||||||
response = client.public_send("get", "/api/sources/get_user_info_by_login", req_params)
|
|
||||||
result = JSON.parse(response.body)
|
|
||||||
|
|
||||||
return nil if result["status"].to_s != "0"
|
|
||||||
|
|
||||||
# login 邮箱 手机号 姓名 学校/单位
|
|
||||||
user_info = result["data"]
|
|
||||||
|
|
||||||
return user_info
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,12 +0,0 @@
|
||||||
class Api::V1::Issues::AssignersController < Api::V1::BaseController
|
|
||||||
|
|
||||||
before_action :require_public_and_member_above, only: [:index]
|
|
||||||
|
|
||||||
# 负责人列表
|
|
||||||
def index
|
|
||||||
@assigners = User.joins(assigned_issues: :project).where(projects: {id: @project&.id})
|
|
||||||
@assigners = @assigners.order("users.id=#{current_user.id} desc").distinct
|
|
||||||
@assigners = @assigners.ransack(login_or_nickname_cont: params[:keyword]).result if params[:keyword].present?
|
|
||||||
@assigners = kaminary_select_paginate(@assigners)
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,11 +0,0 @@
|
||||||
class Api::V1::Issues::AuthorsController < Api::V1::BaseController
|
|
||||||
before_action :require_public_and_member_above, only: [:index]
|
|
||||||
|
|
||||||
# 发布人列表
|
|
||||||
def index
|
|
||||||
@authors = User.joins(issues: :project).where(projects: {id: @project&.id})
|
|
||||||
@authors = @authors.order("users.id=#{current_user.id} desc").distinct
|
|
||||||
@authors = @authors.ransack(login_or_nickname_cont: params[:keyword]).result if params[:keyword].present?
|
|
||||||
@authors = kaminary_select_paginate(@authors)
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,18 +0,0 @@
|
||||||
class Api::V1::Issues::IssuePrioritiesController < Api::V1::BaseController
|
|
||||||
|
|
||||||
before_action :require_public_and_member_above, only: [:index]
|
|
||||||
|
|
||||||
def index
|
|
||||||
@priorities = IssuePriority.order(position: :asc)
|
|
||||||
@priorities = @priorities.ransack(name_cont: params[:keyword]).result if params[:keyword]
|
|
||||||
@priorities = kaminary_select_paginate(@priorities)
|
|
||||||
end
|
|
||||||
|
|
||||||
def pm_index
|
|
||||||
@priorities = IssuePriority.order(position: :asc)
|
|
||||||
@priorities = @priorities.ransack(name_cont: params[:keyword]).result if params[:keyword]
|
|
||||||
@priorities = kaminary_select_paginate(@priorities)
|
|
||||||
render "index"
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
|
@ -1,70 +0,0 @@
|
||||||
class Api::V1::Issues::IssueTagsController < Api::V1::BaseController
|
|
||||||
before_action :require_login, except: [:index, :pm_index]
|
|
||||||
before_action :require_public_and_member_above, only: [:index]
|
|
||||||
before_action :require_operate_above, only: [:create, :update, :destroy]
|
|
||||||
|
|
||||||
def index
|
|
||||||
@issue_tags = @project.issue_tags.reorder("#{sort_by} #{sort_direction}")
|
|
||||||
@issue_tags = @issue_tags.ransack(name_cont: params[:keyword]).result if params[:keyword].present?
|
|
||||||
if params[:only_name]
|
|
||||||
@issue_tags = kaminary_select_paginate(@issue_tags.select(:id, :name, :color))
|
|
||||||
else
|
|
||||||
@issue_tags = kaminari_paginate(@issue_tags.includes(:project, :user, :issue_issues, :pull_request_issues))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def pm_index
|
|
||||||
@issue_tags = IssueTag.init_mp_issues_tags
|
|
||||||
render_ok(@issue_tags)
|
|
||||||
end
|
|
||||||
|
|
||||||
def create
|
|
||||||
@issue_tag = @project.issue_tags.new(issue_tag_params)
|
|
||||||
if @issue_tag.save!
|
|
||||||
render_ok
|
|
||||||
else
|
|
||||||
render_error("创建标记失败!")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
before_action :load_issue_tag, only: [:update, :destroy]
|
|
||||||
|
|
||||||
def update
|
|
||||||
@issue_tag.attributes = issue_tag_params
|
|
||||||
if @issue_tag.save!
|
|
||||||
render_ok
|
|
||||||
else
|
|
||||||
render_error("更新标记失败!")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def destroy
|
|
||||||
if @issue_tag.destroy!
|
|
||||||
render_ok
|
|
||||||
else
|
|
||||||
render_error("删除标记失败!")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
private
|
|
||||||
def sort_by
|
|
||||||
sort_by = params.fetch(:sort_by, "created_at")
|
|
||||||
sort_by = IssueTag.column_names.include?(sort_by) ? sort_by : "created_at"
|
|
||||||
sort_by
|
|
||||||
end
|
|
||||||
|
|
||||||
def sort_direction
|
|
||||||
sort_direction = params.fetch(:sort_direction, "desc").downcase
|
|
||||||
sort_direction = %w(desc asc).include?(sort_direction) ? sort_direction : "desc"
|
|
||||||
sort_direction
|
|
||||||
end
|
|
||||||
|
|
||||||
def issue_tag_params
|
|
||||||
params.permit(:name, :description, :color)
|
|
||||||
end
|
|
||||||
|
|
||||||
def load_issue_tag
|
|
||||||
@issue_tag = @project.issue_tags.find_by_id(params[:id])
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,64 +0,0 @@
|
||||||
class Api::V1::Issues::JournalsController < Api::V1::BaseController
|
|
||||||
before_action :require_login, except: [:index, :children_journals]
|
|
||||||
before_action :require_public_and_member_above
|
|
||||||
before_action :load_issue
|
|
||||||
before_action :load_journal, only: [:children_journals, :update, :destroy]
|
|
||||||
before_action :check_journal_operate_permission, only: [:update, :destroy]
|
|
||||||
|
|
||||||
def index
|
|
||||||
@object_result = Api::V1::Issues::Journals::ListService.call(@issue, query_params, current_user)
|
|
||||||
@total_journals_count = @object_result[:total_journals_count]
|
|
||||||
@total_operate_journals_count = @object_result[:total_operate_journals_count]
|
|
||||||
@total_comment_journals_count = @object_result[:total_comment_journals_count]
|
|
||||||
@journals = kaminary_select_paginate(@object_result[:data])
|
|
||||||
end
|
|
||||||
|
|
||||||
def create
|
|
||||||
@object_result = Api::V1::Issues::Journals::CreateService.call(@issue, journal_params, current_user)
|
|
||||||
end
|
|
||||||
|
|
||||||
def children_journals
|
|
||||||
@object_results = Api::V1::Issues::Journals::ChildrenListService.call(@issue, @journal, query_params, current_user)
|
|
||||||
@journals = kaminari_paginate(@object_results)
|
|
||||||
end
|
|
||||||
|
|
||||||
def update
|
|
||||||
@object_result = Api::V1::Issues::Journals::UpdateService.call(@issue, @journal, journal_params, current_user)
|
|
||||||
end
|
|
||||||
|
|
||||||
def destroy
|
|
||||||
TouchWebhookJob.set(wait: 5.seconds).perform_later('IssueComment', @issue&.id, current_user.id, @journal.id, 'deleted', JSON.parse(@journal.to_builder.target!))
|
|
||||||
if @journal.destroy!
|
|
||||||
render_ok
|
|
||||||
else
|
|
||||||
render_error("删除评论失败!")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def query_params
|
|
||||||
params.permit(:category, :keyword, :sort_by, :sort_direction)
|
|
||||||
end
|
|
||||||
|
|
||||||
def journal_params
|
|
||||||
params.permit(:notes, :parent_id, :reply_id, :attachment_ids => [], :receivers_login => [])
|
|
||||||
end
|
|
||||||
|
|
||||||
def load_issue
|
|
||||||
@issue = @project.issues.issue_issue.where(project_issues_index: params[:index]).where.not(id: params[:index]).take || Issue.find_by_id(params[:index])
|
|
||||||
if @issue.blank?
|
|
||||||
render_not_found("疑修不存在!")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def load_journal
|
|
||||||
@journal = Journal.find_by_id(params[:id])
|
|
||||||
return render_not_found("评论不存在!") unless @journal.present?
|
|
||||||
end
|
|
||||||
|
|
||||||
def check_journal_operate_permission
|
|
||||||
return render_forbidden("您没有操作权限!") unless @project.member?(current_user) || current_user.admin? || @issue.user == current_user || @journal.user == current_user || @journal.parent_journal&.user == current_user
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
|
@ -1,87 +0,0 @@
|
||||||
class Api::V1::Issues::MilestonesController < Api::V1::BaseController
|
|
||||||
before_action :require_login, except: [:index, :show]
|
|
||||||
before_action :require_public_and_member_above, only: [:index, :show]
|
|
||||||
before_action :require_operate_above, only: [:create, :update, :destroy]
|
|
||||||
before_action :load_milestone, only: [:show, :update, :destroy]
|
|
||||||
|
|
||||||
# 里程碑列表
|
|
||||||
def index
|
|
||||||
@milestones = @project.versions
|
|
||||||
@milestones = @milestones.ransack(id_eq: params[:keyword]).result.or(@milestones.ransack(name_or_description_cont: params[:keyword]).result) if params[:keyword].present?
|
|
||||||
@closed_milestone_count = @milestones.closed.size
|
|
||||||
@opening_milestone_count = @milestones.opening.size
|
|
||||||
@milestones = params[:category] == "closed" ? @milestones.closed : @milestones.opening
|
|
||||||
@milestones = @milestones.reorder("versions.#{sort_by} #{sort_direction}")
|
|
||||||
if params[:only_name]
|
|
||||||
@milestones = @milestones.select(:id, :name)
|
|
||||||
@milestones = kaminary_select_paginate(@milestones)
|
|
||||||
else
|
|
||||||
@milestones = @milestones.includes(:issues, :closed_issues, :opened_issues)
|
|
||||||
@milestones = kaminari_paginate(@milestones)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def create
|
|
||||||
@milestone = @project.versions.new(milestone_params)
|
|
||||||
if @milestone.save!
|
|
||||||
render_ok
|
|
||||||
else
|
|
||||||
render_error(@milestone.errors.full_messages.join(","))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# 里程碑详情
|
|
||||||
def show
|
|
||||||
@object_result = Api::V1::Issues::Milestones::DetailIssuesService.call(@project, @milestone, query_params, current_user)
|
|
||||||
@total_issues_count = @object_result[:total_issues_count]
|
|
||||||
@opened_issues_count = @object_result[:opened_issues_count]
|
|
||||||
@closed_issues_count = @object_result[:closed_issues_count]
|
|
||||||
|
|
||||||
@issues = kaminari_paginate(@object_result[:data])
|
|
||||||
end
|
|
||||||
|
|
||||||
def update
|
|
||||||
@milestone.attributes = milestone_params
|
|
||||||
if @milestone.save!
|
|
||||||
render_ok
|
|
||||||
else
|
|
||||||
render_error(@milestone.errors.full_messages.join(","))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def destroy
|
|
||||||
if @milestone.destroy!
|
|
||||||
render_ok
|
|
||||||
else
|
|
||||||
render_error("删除里程碑失败!")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
def milestone_params
|
|
||||||
params.permit(:name, :description, :effective_date)
|
|
||||||
end
|
|
||||||
|
|
||||||
def query_params
|
|
||||||
params.permit(:category, :author_id, :assigner_id, :sort_by, :sort_direction, :issue_tag_ids)
|
|
||||||
end
|
|
||||||
|
|
||||||
def load_milestone
|
|
||||||
@milestone = @project.versions.find_by_id(params[:id])
|
|
||||||
return render_not_found('里程碑不存在!') unless @milestone.present?
|
|
||||||
end
|
|
||||||
|
|
||||||
def sort_by
|
|
||||||
sort_by = params.fetch(:sort_by, "created_on")
|
|
||||||
sort_by = Version.column_names.include?(sort_by) ? sort_by : "created_on"
|
|
||||||
|
|
||||||
sort_by
|
|
||||||
end
|
|
||||||
|
|
||||||
def sort_direction
|
|
||||||
sort_direction = params.fetch(:sort_direction, "desc").downcase
|
|
||||||
sort_direction = %w(desc asc).include?(sort_direction) ? sort_direction : "desc"
|
|
||||||
sort_direction
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
|
@ -1,18 +0,0 @@
|
||||||
class Api::V1::Issues::StatuesController < Api::V1::BaseController
|
|
||||||
|
|
||||||
before_action :require_public_and_member_above, only: [:index]
|
|
||||||
|
|
||||||
# 状态列表
|
|
||||||
def index
|
|
||||||
@statues = IssueStatus.order("position asc")
|
|
||||||
@statues = @statues.ransack(name_cont: params[:keyword]).result if params[:keyword].present?
|
|
||||||
@statues = kaminary_select_paginate(@statues)
|
|
||||||
end
|
|
||||||
|
|
||||||
def pm_index
|
|
||||||
@statues = IssueStatus.order("position asc")
|
|
||||||
@statues = @statues.ransack(name_cont: params[:keyword]).result if params[:keyword].present?
|
|
||||||
@statues = kaminary_select_paginate(@statues)
|
|
||||||
render "index"
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,131 +0,0 @@
|
||||||
class Api::V1::IssuesController < Api::V1::BaseController
|
|
||||||
before_action :require_login, except: [:index, :show, :show_by_id]
|
|
||||||
before_action :require_public_and_member_above, only: [:index, :show, :show_by_id, :create, :update, :destroy]
|
|
||||||
before_action :require_operate_above, only: [:batch_update, :batch_destroy]
|
|
||||||
|
|
||||||
def index
|
|
||||||
IssueTag.init_data(@project.id) unless $redis_cache.hget("project_init_issue_tags", @project.id)
|
|
||||||
@object_result = Api::V1::Issues::ListService.call(@project, query_params, current_user)
|
|
||||||
@total_issues_count = @object_result[:total_issues_count]
|
|
||||||
@opened_issues_count = @object_result[:opened_issues_count]
|
|
||||||
@closed_issues_count = @object_result[:closed_issues_count]
|
|
||||||
if params[:only_name].present?
|
|
||||||
@issues = kaminary_select_paginate(@object_result[:data].select(:id, :subject, :project_issues_index, :updated_on, :created_on))
|
|
||||||
else
|
|
||||||
@issues = kaminari_paginate(@object_result[:data])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def create
|
|
||||||
@object_result = Api::V1::Issues::CreateService.call(@project, issue_params, current_user)
|
|
||||||
end
|
|
||||||
|
|
||||||
before_action :load_issue, only: [:show, :update, :destroy]
|
|
||||||
before_action :check_issue_operate_permission, only: [:update, :destroy]
|
|
||||||
before_action :load_issue_by_id, only: [:show_by_id]
|
|
||||||
|
|
||||||
def show_by_id
|
|
||||||
@issue.associate_attachment_container
|
|
||||||
@user_permission = current_user.present? && current_user.logged? && (@project.member?(current_user) || current_user.admin? || @issue.user == current_user)
|
|
||||||
end
|
|
||||||
|
|
||||||
def show
|
|
||||||
@issue.associate_attachment_container
|
|
||||||
@user_permission = current_user.present? && current_user.logged? && (@project.member?(current_user) || current_user.admin? || @issue.user == current_user)
|
|
||||||
end
|
|
||||||
|
|
||||||
def update
|
|
||||||
@object_result = Api::V1::Issues::UpdateService.call(@project, @issue, issue_params, current_user)
|
|
||||||
end
|
|
||||||
|
|
||||||
def destroy
|
|
||||||
@object_result = Api::V1::Issues::DeleteService.call(@project, @issue, current_user)
|
|
||||||
if @object_result
|
|
||||||
render_ok
|
|
||||||
else
|
|
||||||
render_error("删除疑修失败!")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
before_action :load_issues, only: [:batch_update, :batch_destroy]
|
|
||||||
|
|
||||||
def batch_update
|
|
||||||
@object_result = Api::V1::Issues::BatchUpdateService.call(@project, @issues, batch_issue_params, current_user)
|
|
||||||
if @object_result
|
|
||||||
render_ok
|
|
||||||
else
|
|
||||||
render_error("批量更新疑修失败!")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def batch_destroy
|
|
||||||
@object_result = Api::V1::Issues::BatchDeleteService.call(@project, @issues, current_user)
|
|
||||||
if @object_result
|
|
||||||
render_ok
|
|
||||||
else
|
|
||||||
render_error("批量删除疑修失败!")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def load_issue
|
|
||||||
@issue = @project.issues.issue_issue.where(project_issues_index: params[:index]).where.not(id: params[:index]).take || Issue.find_by_id(params[:index])
|
|
||||||
if @issue.blank?
|
|
||||||
render_not_found("疑修不存在!")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def load_issue_by_id
|
|
||||||
@issue = Issue.find_by_id(params[:index])
|
|
||||||
if @issue.blank?
|
|
||||||
render_not_found("疑修不存在!")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def load_issues
|
|
||||||
return render_error("请输入正确的ID数组!") unless params[:ids].is_a?(Array)
|
|
||||||
params[:ids].each do |id|
|
|
||||||
@issue = Issue.find_by_id(id)
|
|
||||||
if @issue.blank?
|
|
||||||
return render_not_found("ID为#{id}的疑修不存在!")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@issues = Issue.where(id: params[:ids])
|
|
||||||
end
|
|
||||||
|
|
||||||
def check_issue_operate_permission
|
|
||||||
return render_forbidden("您没有操作权限!") unless @project.member?(current_user) || current_user.admin? || @issue.user == current_user
|
|
||||||
end
|
|
||||||
|
|
||||||
def query_params
|
|
||||||
params.permit(
|
|
||||||
:only_name,
|
|
||||||
:category,
|
|
||||||
:participant_category,
|
|
||||||
:keyword, :author_id,
|
|
||||||
:milestone_id, :assigner_id,
|
|
||||||
:status_id,
|
|
||||||
:begin_date, :end_date,
|
|
||||||
:sort_by, :sort_direction,
|
|
||||||
:issue_tag_ids)
|
|
||||||
end
|
|
||||||
|
|
||||||
def issue_params
|
|
||||||
params.permit(
|
|
||||||
:status_id, :priority_id, :milestone_id,
|
|
||||||
:branch_name, :start_date, :due_date,
|
|
||||||
:subject, :description, :blockchain_token_num,
|
|
||||||
:issue_tag_ids => [],
|
|
||||||
:assigner_ids => [],
|
|
||||||
:attachment_ids => [],
|
|
||||||
:receivers_login => [])
|
|
||||||
end
|
|
||||||
|
|
||||||
def batch_issue_params
|
|
||||||
params.permit(
|
|
||||||
:status_id, :priority_id, :milestone_id,
|
|
||||||
:issue_tag_ids => [],
|
|
||||||
:assigner_ids => [])
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,10 +0,0 @@
|
||||||
class Api::V1::ProjectDatasetsController < Api::V1::BaseController
|
|
||||||
|
|
||||||
def index
|
|
||||||
return render_error("请输入正确的项目id字符串") unless params[:ids].present?
|
|
||||||
ids = params[:ids].split(",")
|
|
||||||
@project_datasets = ProjectDataset.where(project_id: ids).includes(:license, :project)
|
|
||||||
@project_datasets = kaminari_unlimit_paginate(@project_datasets)
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
|
@ -1,46 +0,0 @@
|
||||||
class Api::V1::ProjectTopicsController < Api::V1::BaseController
|
|
||||||
|
|
||||||
def index
|
|
||||||
@project_topics = ProjectTopic
|
|
||||||
@project_topics = @project_topics.ransack(name_cont: params[:keyword]) if params[:keyword].present?
|
|
||||||
# @project_topics = @project_topics.includes(:projects)
|
|
||||||
@project_topics = kaminary_select_paginate(@project_topics)
|
|
||||||
end
|
|
||||||
|
|
||||||
def create
|
|
||||||
ActiveRecord::Base.transaction do
|
|
||||||
@project = Project.find_by_id(create_params[:project_id])
|
|
||||||
return render_not_found unless @project.present?
|
|
||||||
return render_error("请输入项目搜索标签名称.") unless create_params[:name].present?
|
|
||||||
|
|
||||||
@project_topic = ProjectTopic.find_or_create_by!(name: create_params[:name].downcase)
|
|
||||||
@project_topic_ralate = @project_topic.project_topic_ralates.find_or_create_by!(project_id: create_params[:project_id])
|
|
||||||
|
|
||||||
if @project_topic.present? && @project_topic_ralate.present?
|
|
||||||
render_ok
|
|
||||||
else
|
|
||||||
render_error("项目关联搜索标签失败.")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def destroy
|
|
||||||
ActiveRecord::Base.transaction do
|
|
||||||
@project = Project.find_by_id(create_params[:project_id])
|
|
||||||
return render_not_found unless @project.present?
|
|
||||||
|
|
||||||
@project_topic = ProjectTopic.find_by_id(params[:id])
|
|
||||||
@project_topic_ralate = @project_topic.project_topic_ralates.find_by(project_id: @project.id)
|
|
||||||
if @project_topic_ralate.destroy!
|
|
||||||
render_ok
|
|
||||||
else
|
|
||||||
render_error("项目取消关联搜索标签失败.")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
def create_params
|
|
||||||
params.permit(:project_id, :name)
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,31 +0,0 @@
|
||||||
class Api::V1::Projects::Actions::ActionsController < Api::V1::Projects::Actions::BaseController
|
|
||||||
|
|
||||||
def index
|
|
||||||
begin
|
|
||||||
gitea_result = $gitea_hat_client.get_repos_actions_by_owner_repo(@project&.owner&.login, @project&.identifier)
|
|
||||||
@data = gitea_result[:data]["Workflows"]
|
|
||||||
rescue
|
|
||||||
@data = []
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def disable
|
|
||||||
return render_error("请输入正确的流水线文件!") if params[:workflow].blank?
|
|
||||||
gitea_result = $gitea_hat_client.post_repos_actions_disable(@project&.owner&.login, @project&.identifier, {query: {workflow: params[:workflow]}}) rescue nil
|
|
||||||
if gitea_result
|
|
||||||
render_ok
|
|
||||||
else
|
|
||||||
render_error("禁用流水线失败")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def enable
|
|
||||||
return render_error("请输入正确的流水线文件!") if params[:workflow].blank?
|
|
||||||
gitea_result = $gitea_hat_client.post_repos_actions_enable(@project&.owner&.login, @project&.identifier, {query: {workflow: params[:workflow]}}) rescue nil
|
|
||||||
if gitea_result
|
|
||||||
render_ok
|
|
||||||
else
|
|
||||||
render_error("取消禁用流水线失败")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,4 +0,0 @@
|
||||||
class Api::V1::Projects::Actions::BaseController < Api::V1::BaseController
|
|
||||||
before_action :require_public_and_member_above
|
|
||||||
|
|
||||||
end
|
|
|
@ -1,57 +0,0 @@
|
||||||
class Api::V1::Projects::Actions::RunsController < Api::V1::Projects::Actions::BaseController
|
|
||||||
|
|
||||||
def index
|
|
||||||
@result_object = Api::V1::Projects::Actions::Runs::ListService.call(@project, {workflow: params[:workflow], page: page, limit: limit}, current_user&.gitea_token)
|
|
||||||
puts @result_object
|
|
||||||
end
|
|
||||||
|
|
||||||
def create
|
|
||||||
return render_error("请输入正确的流水线文件!") if params[:workflow].blank?
|
|
||||||
return render_error("请输入正确的分支!") if params[:ref].blank?
|
|
||||||
gitea_result = $gitea_hat_client.post_repos_actions_runs_by_owner_repo(@project&.owner&.login, @project&.identifier, {query: {workflow: params[:workflow], ref: params[:ref]}})
|
|
||||||
if gitea_result
|
|
||||||
render_ok
|
|
||||||
else
|
|
||||||
ender_error("启动流水线任务失败")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def rerun
|
|
||||||
return render_error("请输入正确的流水线记录ID!") if params[:run_id].blank?
|
|
||||||
gitea_result = $gitea_hat_client.post_repos_actions_runs_rerun_by_owner_repo_run(@project&.owner&.login, @project&.identifier, params[:run_id]) rescue nil
|
|
||||||
if gitea_result
|
|
||||||
render_ok
|
|
||||||
else
|
|
||||||
render_error("重启所有流水线任务失败")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def job_rerun
|
|
||||||
return render_error("请输入正确的流水线记录ID!") if params[:run_id].blank?
|
|
||||||
return render_error("请输入正确的流水线任务ID") if params[:job].blank?
|
|
||||||
gitea_result = $gitea_hat_client.post_repos_actions_runs_jobs_rerun_by_owner_repo_run_job(@project&.owner&.login, @project&.identifier, params[:run_id], params[:job]) rescue nil
|
|
||||||
if gitea_result
|
|
||||||
render_ok
|
|
||||||
else
|
|
||||||
render_error("重启流水线任务失败")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def job_show
|
|
||||||
@result_object = Api::V1::Projects::Actions::Runs::JobShowService.call(@project, params[:run_id], params[:job], params[:log_cursors], current_user&.gitea_token)
|
|
||||||
end
|
|
||||||
|
|
||||||
def job_logs
|
|
||||||
return render_error("请输入正确的流水线记录ID!") if params[:run_id].blank?
|
|
||||||
return render_error("请输入正确的流水线任务ID") if params[:job].blank?
|
|
||||||
domain = GiteaService.gitea_config[:domain]
|
|
||||||
api_url = GiteaService.gitea_config[:hat_base_url]
|
|
||||||
|
|
||||||
url = "/repos/#{@owner.login}/#{@repository.identifier}/actions/runs/#{CGI.escape(params[:run_id])}/jobs/#{CGI.escape(params[:job])}/logs"
|
|
||||||
file_path = [domain, api_url, url].join
|
|
||||||
file_path = [file_path, "access_token=#{@owner&.gitea_token}"].join("?")
|
|
||||||
|
|
||||||
redirect_to file_path
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
|
@ -1,98 +0,0 @@
|
||||||
class Api::V1::Projects::BranchesController < Api::V1::BaseController
|
|
||||||
before_action :require_public_and_member_above, only: [:index, :all]
|
|
||||||
|
|
||||||
def gitee
|
|
||||||
url = URI("https://gitee.com/api/v5/repos/#{params[:owner]}/#{params[:repo]}/branches?access_token=#{params[:token]}&page=#{page}&per_page=#{limit}")
|
|
||||||
https = Net::HTTP.new(url.host, url.port)
|
|
||||||
https.use_ssl = true
|
|
||||||
request = Net::HTTP::Get.new(url)
|
|
||||||
response = https.request(request)
|
|
||||||
render :json => response.read_body
|
|
||||||
end
|
|
||||||
|
|
||||||
def github
|
|
||||||
url = URI("https://api.github.com/repos/#{params[:owner]}/#{params[:repo]}/branches?page=#{page}&per_page=#{limit}")
|
|
||||||
https = Net::HTTP.new(url.host, url.port)
|
|
||||||
https.use_ssl = true
|
|
||||||
|
|
||||||
request = Net::HTTP::Get.new(url)
|
|
||||||
request["Authorization"] = "Bearer #{params[:token]}"
|
|
||||||
request["Accept"] = "application/vnd.github+json"
|
|
||||||
request["X-GitHub-Api-Version"] = "2022-11-28"
|
|
||||||
|
|
||||||
response = https.request(request)
|
|
||||||
render :json => response.read_body
|
|
||||||
end
|
|
||||||
|
|
||||||
def index
|
|
||||||
@result_object = Api::V1::Projects::Branches::ListService.call(@project, {name: params[:keyword], state: params[:state], page: page, limit: limit}, current_user&.gitea_token)
|
|
||||||
end
|
|
||||||
|
|
||||||
def all
|
|
||||||
@result_object = Api::V1::Projects::Branches::AllListService.call(@project, current_user&.gitea_token)
|
|
||||||
end
|
|
||||||
|
|
||||||
before_action :require_operate_above, only: [:create, :destroy, :restore]
|
|
||||||
|
|
||||||
def create
|
|
||||||
@result_object = Api::V1::Projects::Branches::CreateService.call(@project, branch_params, current_user&.gitea_token)
|
|
||||||
end
|
|
||||||
|
|
||||||
def destroy
|
|
||||||
@result_object = Api::V1::Projects::Branches::DeleteService.call(@project, params[:name], current_user&.gitea_token)
|
|
||||||
if @result_object
|
|
||||||
# 有开启的pr需要一同关闭
|
|
||||||
# 1、删除本仓库中存在未关闭的pr,即本仓库分支1->分支2
|
|
||||||
# 2、如果是fork仓库,考虑删除主仓库中存在未关闭的pr,即本仓库:分支1->主:分支2,同时分两种删除:1删除本仓库分支1,2删除主仓库分支2
|
|
||||||
close_pull_requests_by(@project, params[:name])
|
|
||||||
if @project.forked_from_project_id.present?
|
|
||||||
# fork项目中删除分支
|
|
||||||
close_pull_requests_by(@project.fork_project, params[:name])
|
|
||||||
end
|
|
||||||
|
|
||||||
return render_ok
|
|
||||||
else
|
|
||||||
return render_error('删除分支失败!')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def restore
|
|
||||||
@result_object = Api::V1::Projects::Branches::RestoreService.call(@project, params[:branch_id], params[:branch_name], current_user&.gitea_token)
|
|
||||||
if @result_object
|
|
||||||
return render_ok
|
|
||||||
else
|
|
||||||
return render_error('恢复分支失败!')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
before_action :require_manager_above, only: [:update_default_branch]
|
|
||||||
|
|
||||||
def update_default_branch
|
|
||||||
@result_object = Api::V1::Projects::Branches::UpdateDefaultBranchService.call(@project, params[:name], current_user&.gitea_token)
|
|
||||||
if @result_object
|
|
||||||
return render_ok
|
|
||||||
else
|
|
||||||
return render_error('更新默认分支失败!')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
def branch_params
|
|
||||||
params.require(:branch).permit(:new_branch_name, :old_branch_name)
|
|
||||||
end
|
|
||||||
|
|
||||||
def close_pull_requests_by(project, branch_name)
|
|
||||||
open_pull_requests = project.pull_requests.opening.where(head: branch_name).or(project.pull_requests.opening.where(base: branch_name))
|
|
||||||
if open_pull_requests.present?
|
|
||||||
open_pull_requests.each do |pull_request|
|
|
||||||
closed = PullRequests::CloseService.call(project.owner, project.repository, pull_request, current_user)
|
|
||||||
if closed === true
|
|
||||||
pull_request.project_trends.create!(user: current_user, project: project,action_type: ProjectTrend::CLOSE)
|
|
||||||
# 合并请求下issue处理为关闭
|
|
||||||
pull_request.issue&.update_attributes!({status_id:5})
|
|
||||||
SendTemplateMessageJob.perform_later('PullRequestClosed', current_user.id, pull_request.id) if Site.has_notice_menu?
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,8 +0,0 @@
|
||||||
class Api::V1::Projects::CodeStatsController < Api::V1::BaseController
|
|
||||||
before_action :require_public_and_member_above, only: [:index]
|
|
||||||
|
|
||||||
def index
|
|
||||||
@result_object = Api::V1::Projects::CodeStats::ListService.call(@project, {ref: params[:ref]}, current_user&.gitea_token)
|
|
||||||
# puts @result_object
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,10 +0,0 @@
|
||||||
class Api::V1::Projects::CollaboratorsController < Api::V1::BaseController
|
|
||||||
|
|
||||||
before_action :require_public_and_member_above, only: [:index]
|
|
||||||
|
|
||||||
def index
|
|
||||||
@collaborators = @project.all_collaborators.like(params[:keyword])
|
|
||||||
@collaborators = kaminary_select_paginate(@collaborators)
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
|
@ -1,19 +0,0 @@
|
||||||
class Api::V1::Projects::CommitsController < Api::V1::BaseController
|
|
||||||
before_action :require_public_and_member_above, only: [:index, :diff, :recent]
|
|
||||||
|
|
||||||
def index
|
|
||||||
@result_object = Api::V1::Projects::Commits::ListService.call(@project, {page: page, limit: limit, sha: params[:sha]}, current_user&.gitea_token)
|
|
||||||
puts @result_object
|
|
||||||
end
|
|
||||||
|
|
||||||
def diff
|
|
||||||
@result_object = Api::V1::Projects::Commits::DiffService.call(@project, params[:sha], current_user&.gitea_token)
|
|
||||||
end
|
|
||||||
|
|
||||||
def recent
|
|
||||||
hash = Api::V1::Projects::Commits::RecentService.call(@project, {keyword: params[:keyword], page: page, limit: limit}, current_user&.gitea_token)
|
|
||||||
@result_object = hash[:result]
|
|
||||||
@object_detail = hash[:detail]
|
|
||||||
puts @object_detail
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,17 +0,0 @@
|
||||||
class Api::V1::Projects::ContentsController < Api::V1::BaseController
|
|
||||||
before_action :require_operate_above_or_fork_project, only: [:batch]
|
|
||||||
|
|
||||||
def batch
|
|
||||||
@batch_content_params = batch_content_params
|
|
||||||
# 处理下author和committer信息,如果没传则默认为当前用户信息
|
|
||||||
@batch_content_params.merge!(author_email: current_user.mail, author_name: current_user.login) if batch_content_params[:author_email].blank? && batch_content_params[:author_name].blank?
|
|
||||||
@batch_content_params.merge!(committer_email: current_user.mail, committer_name: current_user.login) if batch_content_params[:committer_email].blank? && batch_content_params[:committer_name].blank?
|
|
||||||
|
|
||||||
@result_object = Api::V1::Projects::Contents::BatchCreateService.call(@project, @batch_content_params, @project.owner.gitea_token)
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
def batch_content_params
|
|
||||||
params.require(:content).permit(:author_email, :author_name, :author_timeunix, :branch, :committer_email, :committer_name, :committer_timeunix, :message, :new_branch, files: [ :action_type, :content, :encoding, :file_path])
|
|
||||||
end
|
|
||||||
end
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue