Compare commits
49 Commits
master
...
dev_local_
Author | SHA1 | Date |
---|---|---|
|
d5b2acfe63 | |
|
29ea3dda26 | |
|
111b91584d | |
|
13ebcca249 | |
|
a37191350d | |
|
b7cea34760 | |
|
7844f65466 | |
|
8909ad2ba8 | |
|
6bc0587168 | |
|
7a82d93c85 | |
|
d13ac9e9fe | |
|
253196e000 | |
|
4d751e6b3e | |
|
755fff03a1 | |
|
a117f0bf73 | |
|
7176d3d2d5 | |
|
8874898ff3 | |
|
9e814ee16a | |
|
fe47840e53 | |
|
afecd95947 | |
|
2ec14f6665 | |
|
1c7e74ed1d | |
|
0a6957f193 | |
|
4bd3d98021 | |
|
14df764275 | |
|
24be0501b7 | |
|
b45fb35ea1 | |
|
3646822ec3 | |
|
9d5609e544 | |
|
3f9a3aacfa | |
|
38458764b4 | |
|
dd94480486 | |
|
3dd62f40df | |
|
a0f13e3a0c | |
|
600235effa | |
|
7578fb9e0a | |
|
c8a356b836 | |
|
eb38b3fda4 | |
|
2c5c03f77c | |
|
67f3a87afc | |
|
b5553e2c97 | |
|
a542b02181 | |
|
b7786fc870 | |
|
31f44685d9 | |
|
41e6d6ab09 | |
|
d24703be75 | |
|
487d548e9f | |
|
07696682ca | |
|
c64f241cf8 |
|
@ -10,8 +10,7 @@
|
||||||
|
|
||||||
# Ignore lock config file
|
# Ignore lock config file
|
||||||
*.log
|
*.log
|
||||||
.rubocop.yml
|
|
||||||
.env
|
|
||||||
# mac
|
# mac
|
||||||
*.DS_Store
|
*.DS_Store
|
||||||
.bashrc
|
.bashrc
|
||||||
|
@ -86,4 +85,3 @@ dump.rdb
|
||||||
.tags*
|
.tags*
|
||||||
ceshi_user.xlsx
|
ceshi_user.xlsx
|
||||||
public/trace_task_results
|
public/trace_task_results
|
||||||
public/项目活跃度排行.xls
|
|
58
Dockerfile
58
Dockerfile
|
@ -1,59 +1,29 @@
|
||||||
FROM ubuntu:20.04
|
FROM registry.cn-hangzhou.aliyuncs.com/gitlink/ruby:2.4.5
|
||||||
RUN apt-get update
|
|
||||||
|
ADD ./ /home/pdl/gitlink
|
||||||
|
|
||||||
|
WORKDIR /home/pdl/gitlink
|
||||||
|
|
||||||
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 "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 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 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 rm -rf Gemfile.lock
|
||||||
|
|
||||||
RUN cp config/configuration.yml.example config/configuration.yml
|
RUN cp config/configuration.yml.example config/configuration.yml
|
||||||
RUN cp config/database-docker.yml.example config/database.yml
|
RUN cp config/database.yml.example config/database.yml
|
||||||
|
RUN cp config/environments/production.rb.example config/environments/production.rb
|
||||||
|
RUN cp config/secrets.yml.example config/secrets.yml
|
||||||
RUN touch config/redis.yml
|
RUN touch config/redis.yml
|
||||||
RUN touch config/elasticsearch.yml
|
RUN touch config/elasticsearch.yml
|
||||||
|
RUN mkdir log
|
||||||
|
|
||||||
RUN /bin/bash -l -c 'bundle install'
|
RUN /bin/bash -l -c 'bundle install'
|
||||||
|
#RUN /bin/bash -l -c 'RAILS_ENV=production rails db:create'
|
||||||
|
#RUN /bin/bash -l -c 'RAILS_ENV=production bundle exec rake sync_table_structure:import_csv'
|
||||||
|
#RUN /bin/bash -l -c 'RAILS_ENV=production rails db:migrate'
|
||||||
|
|
||||||
RUN redis-server &
|
#EXPOSE 4000
|
||||||
|
#RUN /bin/bash -l -c 'RAILS_ENV=production puma'
|
||||||
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'
|
|
11
Gemfile
11
Gemfile
|
@ -1,6 +1,5 @@
|
||||||
#source 'https://gems.ruby-china.com'
|
#source 'https://gems.ruby-china.com'
|
||||||
source 'https://mirrors.cloud.tencent.com/rubygems/'
|
source 'https://mirrors.cloud.tencent.com/rubygems/'
|
||||||
#source 'https://rubygems.org'
|
|
||||||
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'
|
||||||
|
@ -21,13 +20,15 @@ gem 'bootsnap', '>= 1.1.0', require: false
|
||||||
|
|
||||||
gem 'chinese_pinyin'
|
gem 'chinese_pinyin'
|
||||||
|
|
||||||
|
gem 'loofah','~> 2.20.0'
|
||||||
|
|
||||||
gem 'rack-cors'
|
gem 'rack-cors'
|
||||||
gem 'redis-rails'
|
gem 'redis-rails'
|
||||||
gem 'roo-xls'
|
gem 'roo-xls'
|
||||||
gem 'simple_xlsx_reader', '~>1.0.4'
|
gem 'simple_xlsx_reader', '~>1.0.4'
|
||||||
|
|
||||||
gem 'rubyzip'
|
gem 'rubyzip'
|
||||||
gem 'sonarqube', :git => 'https://gitlink.org.cn/KingChan/sonarqube.git'
|
|
||||||
gem 'spreadsheet'
|
gem 'spreadsheet'
|
||||||
gem 'ruby-ole'
|
gem 'ruby-ole'
|
||||||
# 导出为xlsx
|
# 导出为xlsx
|
||||||
|
@ -71,7 +72,6 @@ group :development do
|
||||||
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 'pry-rails'
|
|
||||||
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
|
||||||
|
@ -116,6 +116,7 @@ gem 'aasm'
|
||||||
gem 'enumerize'
|
gem 'enumerize'
|
||||||
|
|
||||||
gem 'diffy'
|
gem 'diffy'
|
||||||
|
|
||||||
gem 'deep_cloneable', '~> 3.0.0'
|
gem 'deep_cloneable', '~> 3.0.0'
|
||||||
|
|
||||||
# oauth2
|
# oauth2
|
||||||
|
@ -142,6 +143,4 @@ gem 'doorkeeper'
|
||||||
|
|
||||||
gem 'doorkeeper-jwt'
|
gem 'doorkeeper-jwt'
|
||||||
|
|
||||||
gem 'gitea-client', '~> 1.6.1'
|
gem 'gitea-client', '~> 1.4.2'
|
||||||
|
|
||||||
gem 'loofah', '~> 2.20.0'
|
|
||||||
|
|
36
Gemfile.lock
36
Gemfile.lock
|
@ -99,7 +99,6 @@ GEM
|
||||||
archive-zip (~> 0.10)
|
archive-zip (~> 0.10)
|
||||||
nokogiri (~> 1.8)
|
nokogiri (~> 1.8)
|
||||||
chunky_png (1.3.11)
|
chunky_png (1.3.11)
|
||||||
coderay (1.1.3)
|
|
||||||
concurrent-ruby (1.1.6)
|
concurrent-ruby (1.1.6)
|
||||||
connection_pool (2.2.2)
|
connection_pool (2.2.2)
|
||||||
crass (1.0.6)
|
crass (1.0.6)
|
||||||
|
@ -136,7 +135,7 @@ 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.5.9)
|
gitea-client (1.4.2)
|
||||||
rest-client (~> 2.1.0)
|
rest-client (~> 2.1.0)
|
||||||
globalid (0.4.2)
|
globalid (0.4.2)
|
||||||
activesupport (>= 4.2.0)
|
activesupport (>= 4.2.0)
|
||||||
|
@ -149,7 +148,7 @@ GEM
|
||||||
hashie (3.6.0)
|
hashie (3.6.0)
|
||||||
htmlentities (4.3.4)
|
htmlentities (4.3.4)
|
||||||
http-accept (1.7.0)
|
http-accept (1.7.0)
|
||||||
http-cookie (1.0.8)
|
http-cookie (1.0.5)
|
||||||
domain_name (~> 0.5)
|
domain_name (~> 0.5)
|
||||||
i18n (1.8.2)
|
i18n (1.8.2)
|
||||||
concurrent-ruby (~> 1.0)
|
concurrent-ruby (~> 1.0)
|
||||||
|
@ -179,8 +178,7 @@ GEM
|
||||||
rb-fsevent (~> 0.9, >= 0.9.4)
|
rb-fsevent (~> 0.9, >= 0.9.4)
|
||||||
rb-inotify (~> 0.9, >= 0.9.7)
|
rb-inotify (~> 0.9, >= 0.9.7)
|
||||||
ruby_dep (~> 1.2)
|
ruby_dep (~> 1.2)
|
||||||
logger (1.6.6)
|
loofah (2.4.0)
|
||||||
loofah (2.20.0)
|
|
||||||
crass (~> 1.0.2)
|
crass (~> 1.0.2)
|
||||||
nokogiri (>= 1.5.9)
|
nokogiri (>= 1.5.9)
|
||||||
mail (2.7.1)
|
mail (2.7.1)
|
||||||
|
@ -189,10 +187,9 @@ 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.6.0)
|
mime-types (3.4.1)
|
||||||
logger
|
|
||||||
mime-types-data (~> 3.2015)
|
mime-types-data (~> 3.2015)
|
||||||
mime-types-data (3.2025.0220)
|
mime-types-data (3.2023.0218.1)
|
||||||
mimemagic (0.3.10)
|
mimemagic (0.3.10)
|
||||||
nokogiri (~> 1)
|
nokogiri (~> 1)
|
||||||
rake
|
rake
|
||||||
|
@ -247,18 +244,14 @@ GEM
|
||||||
popper_js (1.16.0)
|
popper_js (1.16.0)
|
||||||
powerpack (0.1.2)
|
powerpack (0.1.2)
|
||||||
prettier (0.18.2)
|
prettier (0.18.2)
|
||||||
pry (0.12.2)
|
|
||||||
coderay (~> 1.1.0)
|
|
||||||
method_source (~> 0.9.0)
|
|
||||||
pry-rails (0.3.9)
|
|
||||||
pry (>= 0.10.4)
|
|
||||||
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)
|
||||||
|
@ -455,7 +448,9 @@ 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.2.0)
|
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)
|
||||||
|
@ -497,7 +492,7 @@ DEPENDENCIES
|
||||||
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.5.8)
|
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)
|
||||||
|
@ -507,7 +502,6 @@ DEPENDENCIES
|
||||||
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)
|
||||||
loofah (~> 2.20.0)
|
|
||||||
mysql2 (>= 0.4.4, < 0.6.0)
|
mysql2 (>= 0.4.4, < 0.6.0)
|
||||||
oauth2
|
oauth2
|
||||||
omniauth (~> 1.9.0)
|
omniauth (~> 1.9.0)
|
||||||
|
@ -520,9 +514,9 @@ DEPENDENCIES
|
||||||
parallel (~> 1.19, >= 1.19.1)
|
parallel (~> 1.19, >= 1.19.1)
|
||||||
pdfkit
|
pdfkit
|
||||||
prettier
|
prettier
|
||||||
pry-rails
|
puma (~> 3.11)
|
||||||
puma (~> 5.6.5)
|
|
||||||
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
|
||||||
|
@ -544,7 +538,7 @@ DEPENDENCIES
|
||||||
sidekiq-cron (= 1.2.0)
|
sidekiq-cron (= 1.2.0)
|
||||||
sidekiq-failures
|
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
|
||||||
|
|
13
README.md
13
README.md
|
@ -3,8 +3,7 @@
|
||||||
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>
|
||||||
|
|
||||||
|
|
||||||
## 特色功能
|
## 特色功能
|
||||||
|
|
||||||
|
@ -175,31 +174,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>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
//= 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_tree ./i18n
|
//= require_tree ./i18n
|
||||||
//= require_tree ./admins
|
//= require_tree ./admins
|
||||||
|
|
|
@ -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.
|
|
|
@ -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.
|
|
|
@ -40,13 +40,6 @@ body {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.editormd .CodeMirror{
|
|
||||||
margin-top: 35px!important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.CodeMirror-gutter .CodeMirror-linenumbers {
|
|
||||||
width: 28px!important;
|
|
||||||
}
|
|
||||||
|
|
||||||
input.form-control {
|
input.form-control {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
// Place all the styles related to the api/pm/issue_links 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 api/pm/projects 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 api/v1/pm_issues 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 api/v1/sonarqube/issues 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 api/v1/sonarqubes 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 pm/journals controller here.
|
|
||||||
// They will automatically be included in application.css.
|
|
||||||
// You can use Sass (SCSS) here: http://sass-lang.com/
|
|
|
@ -1,7 +1,6 @@
|
||||||
class AccountsController < ApplicationController
|
class AccountsController < ApplicationController
|
||||||
before_action :require_login, only: [:login_check, :simple_update, :change_password]
|
before_action :require_login, only: [:login_check, :simple_update]
|
||||||
include ApplicationHelper
|
include ApplicationHelper
|
||||||
include AesCryptHelper
|
|
||||||
|
|
||||||
#skip_before_action :check_account, :only => [:logout]
|
#skip_before_action :check_account, :only => [:logout]
|
||||||
|
|
||||||
|
@ -32,12 +31,11 @@ class AccountsController < ApplicationController
|
||||||
username = params[:username]&.gsub(/\s+/, "")
|
username = params[:username]&.gsub(/\s+/, "")
|
||||||
tip_exception("无法使用以下关键词:#{username},请重新命名") if ReversedKeyword.check_exists?(username)
|
tip_exception("无法使用以下关键词:#{username},请重新命名") if ReversedKeyword.check_exists?(username)
|
||||||
email = params[:email]&.gsub(/\s+/, "")
|
email = params[:email]&.gsub(/\s+/, "")
|
||||||
phone = params[:phone]&.gsub(/\s+/, "")
|
|
||||||
password = params[:password]
|
password = params[:password]
|
||||||
platform = (params[:platform] || 'forge')&.gsub(/\s+/, "")
|
platform = (params[:platform] || 'forge')&.gsub(/\s+/, "")
|
||||||
|
|
||||||
ActiveRecord::Base.transaction do
|
ActiveRecord::Base.transaction do
|
||||||
result = autologin_register(username, email, password, platform, phone)
|
result = autologin_register(username, email, password, platform)
|
||||||
if result[:message].blank?
|
if result[:message].blank?
|
||||||
render_ok({user: result[:user]})
|
render_ok({user: result[:user]})
|
||||||
else
|
else
|
||||||
|
@ -145,8 +143,7 @@ class AccountsController < ApplicationController
|
||||||
|
|
||||||
user = Users::RegisterService.call(register_params)
|
user = Users::RegisterService.call(register_params)
|
||||||
user.mail = "#{user.login}@example.org" if user.mail.blank?
|
user.mail = "#{user.login}@example.org" if user.mail.blank?
|
||||||
password = decrypt(register_params[:password]) rescue register_params[:password].to_s
|
password = register_params[:password].strip
|
||||||
password = password.strip
|
|
||||||
|
|
||||||
# gitea用户注册, email, username, password
|
# gitea用户注册, email, username, password
|
||||||
interactor = Gitea::RegisterInteractor.call({username: user.login, email: user.mail, password: password})
|
interactor = Gitea::RegisterInteractor.call({username: user.login, email: user.mail, password: password})
|
||||||
|
@ -196,21 +193,20 @@ class AccountsController < ApplicationController
|
||||||
|
|
||||||
# 用户登录
|
# 用户登录
|
||||||
def login
|
def login
|
||||||
password = decrypt(login_params[:password]) rescue login_params[:password].to_s
|
Users::LoginForm.new(login_params).validate!
|
||||||
Users::LoginForm.new(login_params.merge!({password: password})).validate!
|
@user = User.try_to_login(params[:login], params[:password])
|
||||||
@user = User.try_to_login(params[:login], password)
|
|
||||||
|
|
||||||
return normal_status(-2, "错误的账号或密码") if @user.blank?
|
return normal_status(-2, "错误的账号或密码") if @user.blank?
|
||||||
# user is already in local database
|
# user is already in local database
|
||||||
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?(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
|
||||||
|
@ -220,24 +216,19 @@ class AccountsController < ApplicationController
|
||||||
|
|
||||||
LimitForbidControl::UserLogin.new(@user).clear
|
LimitForbidControl::UserLogin.new(@user).clear
|
||||||
successful_authentication(@user)
|
successful_authentication(@user)
|
||||||
sync_pwd_to_gitea!(@user, {password: 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
|
||||||
password = decrypt(params[:password]) rescue params[:password].to_s
|
|
||||||
new_password_repeat = decrypt(params[:new_password_repeat]) rescue params[:new_password_repeat].to_s
|
|
||||||
old_password = decrypt(params[:old_password]) rescue params[:old_password]
|
|
||||||
return render_error("两次输入的密码不一致") if password.to_s != new_password_repeat.to_s
|
|
||||||
@user = User.find_by(login: params[:login])
|
@user = User.find_by(login: params[:login])
|
||||||
return render_forbidden unless User.current.login == @user&.login
|
|
||||||
return render_error("此用户禁止修改密码!") if @user.id.to_i === 104691
|
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?(old_password)
|
return render_error("旧密码不正确") unless @user.check_password?(params[:old_password])
|
||||||
|
|
||||||
sync_params = {
|
sync_params = {
|
||||||
password: password.to_s,
|
password: params[:password].to_s,
|
||||||
email: @user.mail,
|
email: @user.mail,
|
||||||
login_name: @user.name,
|
login_name: @user.name,
|
||||||
source_id: 0
|
source_id: 0
|
||||||
|
@ -245,7 +236,7 @@ class AccountsController < ApplicationController
|
||||||
|
|
||||||
interactor = Gitea::User::UpdateInteractor.call(@user.login, sync_params)
|
interactor = Gitea::User::UpdateInteractor.call(@user.login, sync_params)
|
||||||
if interactor.success?
|
if interactor.success?
|
||||||
@user.update_attribute(:password, password)
|
@user.update_attribute(:password, params[:password])
|
||||||
render_ok
|
render_ok
|
||||||
else
|
else
|
||||||
render_error(interactor.error)
|
render_error(interactor.error)
|
||||||
|
|
|
@ -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{ render_ok(data: @node_inputs.as_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, :default_value)
|
|
||||||
else
|
|
||||||
params.permit(:name, :input_type, :description, :is_required, :sort_no, :default_value)
|
|
||||||
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,74 +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
|
|
||||||
respond_to do |format|
|
|
||||||
format.html
|
|
||||||
format.json { render_ok(data: @node_types.as_json) }
|
|
||||||
end
|
|
||||||
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
|
|
||||||
respond_to do |format|
|
|
||||||
format.html
|
|
||||||
format.json { render_ok(data: @node_type.as_json) }
|
|
||||||
end
|
|
||||||
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
|
|
||||||
respond_to do |format|
|
|
||||||
format.html { redirect_to action_node_types_path }
|
|
||||||
format.json { render_ok }
|
|
||||||
end
|
|
||||||
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,87 +0,0 @@
|
||||||
class Action::NodesController < ApplicationController
|
|
||||||
# before_action :require_admin, except: [:index]
|
|
||||||
before_action :require_login
|
|
||||||
before_action :find_action_node, except: [:index, :create, :new]
|
|
||||||
|
|
||||||
def index
|
|
||||||
@node_types = Action::NodeType.all
|
|
||||||
no_node_type = Action::NodeType.find_by(name: "未分类")
|
|
||||||
@no_type_nodes = Action::Node.where(action_node_types_id: nil)
|
|
||||||
@no_type_nodes = Action::Node.where(action_node_types_id: nil).or(Action::Node.where(action_node_types_id: no_node_type.id)) if no_node_type.present?
|
|
||||||
respond_to do |format|
|
|
||||||
format.html { @nodes = Action::Node.where("name LIKE :search OR full_name LIKE :search", :search => "%#{params[:search]}%") }
|
|
||||||
format.json
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def create
|
|
||||||
@node = Action::Node.new(node_params)
|
|
||||||
if params.require(:node).present? && params.require(:node)[:link_type_array].present?
|
|
||||||
@node.link_type = (params.require(:node)[:link_type_array] - [""]).join(",")
|
|
||||||
end
|
|
||||||
@node.user_id = current_user.id
|
|
||||||
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
|
|
||||||
if @node.link_type.present?
|
|
||||||
@node.link_type_array = @node.link_type.to_s.split(",")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def update
|
|
||||||
if params.require(:node).present? && params.require(:node)[:link_type_array].present?
|
|
||||||
@node.link_type = (params.require(:node)[:link_type_array] - [""]).join(",")
|
|
||||||
end
|
|
||||||
@node.user_id = current_user.id if @node.user_id.blank?
|
|
||||||
@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
|
|
||||||
respond_to do |format|
|
|
||||||
format.html { redirect_to action_nodes_path }
|
|
||||||
format.json { render_ok() }
|
|
||||||
end
|
|
||||||
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, :label, :full_name, :description, :icon, :action_node_types_id,
|
|
||||||
:is_local, :local_url, :yaml, :sort_no, :node_type, :is_mutil_link, :link_type, :link_type_array)
|
|
||||||
else
|
|
||||||
params.permit(:name, :label, :full_name, :description, :icon, :action_node_types_id, :is_local, :local_url,
|
|
||||||
:yaml, :sort_no, :node_type, :is_mutil_link, :link_type, :link_type_array)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,71 +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
|
|
||||||
respond_to do |format|
|
|
||||||
format.html { redirect_to action_templates_path }
|
|
||||||
format.json { render_ok }
|
|
||||||
end
|
|
||||||
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,13 +1,9 @@
|
||||||
class Admins::DashboardsController < Admins::BaseController
|
class Admins::DashboardsController < Admins::BaseController
|
||||||
def index
|
def index
|
||||||
# 查询优化
|
|
||||||
week_greater_id = CommitLog.where(created_at: current_week).limit(1)[0]&.id
|
|
||||||
#月份统计还需要优化
|
|
||||||
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
|
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)
|
weekly_user_ids = CommitLog.where(created_at: current_week).pluck(:user_id).uniq
|
||||||
month_user_ids = CommitLog.where(created_at: current_month).where("id>= ?", month_greater_id).distinct.pluck(:user_id)
|
month_user_ids = CommitLog.where(created_at: current_month).pluck(:user_id).uniq
|
||||||
@active_user_count = User.where(last_login_on: today).or(User.where(id: day_user_ids)).count
|
@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
|
@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
|
@month_active_user_count = User.where(last_login_on: current_month).or(User.where(id: month_user_ids)).count
|
||||||
|
@ -22,78 +18,16 @@ class Admins::DashboardsController < Admins::BaseController
|
||||||
|
|
||||||
# 活跃项目数
|
# 活跃项目数
|
||||||
day_project_ids = (CommitLog.where(created_at: today).pluck(:project_id).uniq + Issue.where(created_on: today).pluck(:project_id).uniq).uniq
|
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
|
weekly_project_ids = (CommitLog.where(created_at: current_week).pluck(:project_id).uniq + 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
|
month_project_ids = (CommitLog.where(created_at: current_month).pluck(:project_id).uniq + 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
|
@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
|
@weekly_active_project_count = Project.where(updated_on: current_week).or(Project.where(id: weekly_project_ids)).count
|
||||||
Project.where(updated_on: current_week).or(Project.where(id: weekly_project_ids)).count
|
@month_active_project_count = Project.where(updated_on: current_month).or(Project.where(id: month_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
|
@day_new_project_count = Project.where(created_on: today).count
|
||||||
Project.where(created_on: today).count
|
@weekly_new_project_count = Project.where(created_on: current_week).count
|
||||||
end
|
@month_new_project_count = Project.where(created_on: current_month).count
|
||||||
@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]
|
|
||||||
|
|
||||||
if EduSetting.get("open_baidu_tongji").to_s == "true"
|
|
||||||
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 || Time.now
|
|
||||||
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)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def month_active_user
|
def month_active_user
|
||||||
|
@ -108,19 +42,6 @@ class Admins::DashboardsController < Admins::BaseController
|
||||||
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,12 +63,8 @@ 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.end_of_day..Time.now.end_of_day
|
||||||
end
|
end
|
||||||
|
|
||||||
def current_month
|
def current_month
|
||||||
|
@ -155,7 +72,6 @@ class Admins::DashboardsController < Admins::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def pre_week
|
def pre_week
|
||||||
# 14.days.ago.end_of_day..7.days.ago.end_of_day
|
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,5 +1,4 @@
|
||||||
class Admins::FeedbacksController < Admins::BaseController
|
class Admins::FeedbacksController < Admins::BaseController
|
||||||
before_action :require_business
|
|
||||||
before_action :get_feedback, only: [:new_history, :create_history, :destroy]
|
before_action :get_feedback, only: [:new_history, :create_history, :destroy]
|
||||||
|
|
||||||
def index
|
def index
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
class Admins::GlccPrCheckController < Admins::BaseController
|
class Admins::GlccPrCheckController < Admins::BaseController
|
||||||
before_action :require_glcc_admin
|
|
||||||
|
|
||||||
def index
|
def index
|
||||||
params[:sort_by] = params[:sort_by].presence || 'created_on'
|
params[:sort_by] = params[:sort_by].presence || 'created_on'
|
||||||
params[:sort_direction] = params[:sort_direction].presence || 'desc'
|
params[:sort_direction] = params[:sort_direction].presence || 'desc'
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
class Admins::IdentityVerificationsController < Admins::BaseController
|
class Admins::IdentityVerificationsController < Admins::BaseController
|
||||||
before_action :require_business
|
|
||||||
before_action :finder_identity_verification, except: [:index]
|
before_action :finder_identity_verification, except: [:index]
|
||||||
def index
|
def index
|
||||||
params[:sort_by] = params[:sort_by].presence || 'created_at'
|
params[:sort_by] = params[:sort_by].presence || 'created_at'
|
||||||
|
@ -15,14 +14,12 @@ class Admins::IdentityVerificationsController < Admins::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
if update_params[:state] == "已拒绝" && update_params[:description].blank?
|
if @identity_verification.update(update_params)
|
||||||
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
|
redirect_to admins_identity_verifications_path
|
||||||
flash[:success] = "更新成功"
|
flash[:success] = "更新成功"
|
||||||
|
else
|
||||||
|
redirect_to admins_identity_verifications_path
|
||||||
|
flash[:danger] = "更新失败"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -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')
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
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
|
||||||
|
@ -8,12 +7,12 @@ class Admins::MessageTemplatesController < Admins::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def new
|
def new
|
||||||
@message_template = MessageTemplate::CustomTip.new
|
@message_template = MessageTemplate.new
|
||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
@message_template = MessageTemplate::CustomTip.new
|
@message_template = MessageTemplate::CustomTip.new(message_template_params)
|
||||||
@message_template.attributes = message_template_params
|
@message_template.type = "MessageTemplate::CustomTip"
|
||||||
if @message_template.save!
|
if @message_template.save!
|
||||||
redirect_to admins_message_templates_path
|
redirect_to admins_message_templates_path
|
||||||
flash[:success] = "创建消息模板成功"
|
flash[:success] = "创建消息模板成功"
|
||||||
|
@ -48,7 +47,9 @@ class Admins::MessageTemplatesController < Admins::BaseController
|
||||||
|
|
||||||
private
|
private
|
||||||
def message_template_params
|
def message_template_params
|
||||||
params.require(@message_template.type.split("::").join("_").underscore.to_sym).permit!
|
# type = @message_template.present? ? @message_template.type : "MessageTemplate::CustomTip"
|
||||||
|
# params.require(type.split("::").join("_").underscore.to_sym).permit!
|
||||||
|
params.require(:message_template_custom_tip).permit!
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_template
|
def get_template
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
class Admins::NpsController < Admins::BaseController
|
class Admins::NpsController < Admins::BaseController
|
||||||
before_action :require_business
|
|
||||||
def index
|
def index
|
||||||
@on_off_switch = EduSetting.get("nps-on-off-switch").to_s == 'true'
|
@on_off_switch = EduSetting.get("nps-on-off-switch").to_s == 'true'
|
||||||
@user_nps = UserNp.order(created_at: :desc)
|
@user_nps = UserNp.joins(:user).order(created_at: :desc)
|
||||||
keyword = params[:keyword].to_s.strip.presence
|
keyword = params[:keyword].to_s.strip.presence
|
||||||
if keyword
|
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'
|
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'
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
class Admins::OrganizationsController < Admins::BaseController
|
class Admins::OrganizationsController < Admins::BaseController
|
||||||
before_action :require_admin
|
before_action :finder_org, except: [:index]
|
||||||
before_action :finder_org, except: [:index]
|
|
||||||
|
|
||||||
def index
|
def index
|
||||||
params[:sort_by] = params[:sort_by].presence || 'created_on'
|
params[:sort_by] = params[:sort_by].presence || 'created_on'
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
class Admins::PageThemesController < Admins::BaseController
|
class Admins::PageThemesController < Admins::BaseController
|
||||||
before_action :require_admin
|
|
||||||
before_action :finder_page_theme, only: [:edit, :update, :destroy]
|
before_action :finder_page_theme, only: [:edit, :update, :destroy]
|
||||||
|
|
||||||
def index
|
def index
|
||||||
|
|
|
@ -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,5 +1,4 @@
|
||||||
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]
|
||||||
|
|
||||||
|
|
|
@ -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]
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
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]
|
||||||
|
|
||||||
|
@ -7,7 +6,7 @@ class Admins::ProjectLicensesController < Admins::BaseController
|
||||||
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
|
||||||
|
|
||||||
|
@ -96,7 +95,7 @@ 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
|
||||||
|
|
|
@ -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("id = ? OR name like ? OR identifier LIKE ?", search, "%#{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,12 +32,8 @@ 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)
|
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
|
||||||
|
@ -67,19 +52,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,60 +1,16 @@
|
||||||
class Admins::ProjectsRankController < Admins::BaseController
|
class Admins::ProjectsRankController < Admins::BaseController
|
||||||
before_action :require_admin
|
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@statistics = DailyProjectStatistic.where("date >= ? AND date <= ?", begin_date, end_date)
|
@rank_date = rank_date
|
||||||
@statistics = @statistics.group(:project_id).select("project_id,
|
deleted_data = $redis_cache.smembers("v2-project-rank-deleted")
|
||||||
sum(score) as score,
|
$redis_cache.zrem("v2-project-rank-#{rank_date}", deleted_data) unless deleted_data.blank?
|
||||||
sum(visits) as visits,
|
@date_rank = $redis_cache.zrevrange("v2-project-rank-#{rank_date}", 0, -1, withscores: true)
|
||||||
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
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def begin_date
|
def rank_date
|
||||||
params.fetch(:begin_date, (Date.yesterday-7.days).to_s)
|
params.fetch(:date, Date.today.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&.project&.project_category&.name
|
|
||||||
sheet[index+1,4] = d&.project&.created_on.present? ? d&.project&.created_on.strftime("%Y-%m-%d %H:%M:%S") : ""
|
|
||||||
sheet[index+1,5] = d&.project&.common? ? "独立创建" : "外部迁移"
|
|
||||||
sheet[index+1,6] = d.score
|
|
||||||
sheet[index+1,7] = d.visits
|
|
||||||
sheet[index+1,8] = d.watchers
|
|
||||||
sheet[index+1,9] = d.praises
|
|
||||||
sheet[index+1,10] = d.forks
|
|
||||||
sheet[index+1,11] = d.issues
|
|
||||||
sheet[index+1,12] = d.pullrequests
|
|
||||||
sheet[index+1,13] = d.commits
|
|
||||||
end
|
|
||||||
book.write "#{Rails.root}/public/项目活跃度排行.xls"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
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,5 +1,4 @@
|
||||||
class Admins::SitePagesController < Admins::BaseController
|
class Admins::SitePagesController < Admins::BaseController
|
||||||
before_action :require_admin
|
|
||||||
before_action :finder_site_page, except: [:index]
|
before_action :finder_site_page, except: [:index]
|
||||||
|
|
||||||
def index
|
def index
|
||||||
|
@ -30,12 +29,8 @@ class Admins::SitePagesController < Admins::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
if update_params[:state] == "false" && update_params[:state_description].blank?
|
@site_page.update(update_params)
|
||||||
flash[:danger] = '关闭站点理由不能为空'
|
flash[:success] = '保存成功'
|
||||||
else
|
|
||||||
@site_page.update(update_params)
|
|
||||||
flash[:success] = '保存成功'
|
|
||||||
end
|
|
||||||
render 'edit'
|
render 'edit'
|
||||||
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,5 +1,4 @@
|
||||||
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
|
||||||
|
|
|
@ -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,14 +0,0 @@
|
||||||
class Admins::UserActionsController < Admins::BaseController
|
|
||||||
before_action :require_admin
|
|
||||||
|
|
||||||
def index
|
|
||||||
@user_actions = UserAction.order(created_at: :desc)
|
|
||||||
@user_actions = @user_actions.where(action_type: params[:action_type]) if params[:action_type].present?
|
|
||||||
keyword = params[:keyword].to_s.strip.presence
|
|
||||||
if keyword
|
|
||||||
sql = 'login LIKE :keyword OR phone LIKE :keyword OR email LIKE :keyword'
|
|
||||||
@user_actions = @user_actions.where(sql, keyword: "%#{keyword}%")
|
|
||||||
end
|
|
||||||
@user_actions = paginate @user_actions
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,5 +1,4 @@
|
||||||
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
|
||||||
|
@ -27,30 +26,10 @@ class Admins::UsersController < Admins::BaseController
|
||||||
|
|
||||||
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)
|
UserAction.create(action_id: @user.id, action_type: "DestroyUser", user_id: current_user.id, :ip => request.remote_ip, data_bank: @user.attributes.to_json)
|
||||||
# org_ids = TeamUser.where(user_id: @user.id).pluck(:organization_id) | OrganizationUser.where(user_id: @user.id).pluck(:organization_id)
|
@user.destroy!
|
||||||
# organizations = Organization.where(id: org_ids)
|
Gitea::User::DeleteService.call(@user.login)
|
||||||
# organizations.each do |org|
|
|
||||||
# # org.team_users.joins(:team).where(user_id: @user.id, teams: {authorize: %w(owner)})
|
|
||||||
# owner_count = org.team_users.joins(:team).where(teams: {authorize: %w(owner)}).count
|
|
||||||
# # 多个owner时,仅将用户从组织移除, 一个时直接删除
|
|
||||||
# if owner_count > 1
|
|
||||||
# org.team_users.joins(:team).where(user_id: @user.id, teams: {authorize: %w(owner)}).destroy_all
|
|
||||||
# org.organization_users.where(user_id: @user.id, organization_id: org.id).destroy_all
|
|
||||||
# else
|
|
||||||
# org.destroy
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
# @user.destroy!
|
|
||||||
# Gitea::User::DeleteService.call(@user.login, true)
|
|
||||||
#
|
|
||||||
# render_delete_success
|
|
||||||
|
|
||||||
@result_object = Api::V1::Users::DeleteUserService.call(@user)
|
render_delete_success
|
||||||
if @result_object
|
|
||||||
render_delete_success
|
|
||||||
else
|
|
||||||
render_js_error('删除失败!')
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def lock
|
def lock
|
||||||
|
@ -94,6 +73,6 @@ class Admins::UsersController < Admins::BaseController
|
||||||
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 technical_title is_shixun_marker
|
||||||
mail phone location location_city school_id department_id admin
|
mail phone location location_city school_id department_id admin
|
||||||
password login website_permission business glcc_admin])
|
password login website_permission])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
class Admins::UsersRankController < Admins::BaseController
|
class Admins::UsersRankController < Admins::BaseController
|
||||||
before_action :require_admin
|
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@rank_date = rank_date
|
@rank_date = rank_date
|
||||||
|
|
|
@ -1,45 +0,0 @@
|
||||||
class Api::Pm::ActionRunsController < Api::Pm::BaseController
|
|
||||||
before_action :require_login
|
|
||||||
|
|
||||||
def index
|
|
||||||
tip_exception('请输入workflows') if params[:workflows].blank?
|
|
||||||
@owner = Owner.find_by(login: params[:owner_id].to_s) || Owner.find_by(id: params[:owner_id].to_s)
|
|
||||||
tip_exception('组织未找到') if @owner.blank?
|
|
||||||
action_runs = Gitea::ActionRun.where(owner_id: @owner.gitea_uid)
|
|
||||||
group_data = action_runs.where(workflow_id: params[:workflows].to_s.split(",")).where(status: [1,2]).group(:workflow_id, :status).count
|
|
||||||
@result = []
|
|
||||||
params[:workflows].to_s.split(",").each do |file|
|
|
||||||
last_action_run = action_runs.where(workflow_id: file).order(updated: :desc).first
|
|
||||||
last_action_run_json = last_action_run.present? ? {
|
|
||||||
id: last_action_run.id,
|
|
||||||
schedule: last_action_run.schedule_id > 0,
|
|
||||||
title: last_action_run.title,
|
|
||||||
index: last_action_run.index,
|
|
||||||
status: last_action_run.status,
|
|
||||||
started: last_action_run.started,
|
|
||||||
stopped: last_action_run.stopped,
|
|
||||||
length: last_action_run.stopped - last_action_run.started,
|
|
||||||
created: last_action_run.created,
|
|
||||||
updated: last_action_run.updated,
|
|
||||||
} : {}
|
|
||||||
|
|
||||||
total = 0
|
|
||||||
success = 0
|
|
||||||
failure = 0
|
|
||||||
group_data.each do |k,v|
|
|
||||||
total += v if k[0] == file
|
|
||||||
success += v if k[0] == file && k[1] == 1
|
|
||||||
failure += v if k[0] == file && k[1] == 2
|
|
||||||
end
|
|
||||||
|
|
||||||
@result << {
|
|
||||||
name: file,
|
|
||||||
total: total,
|
|
||||||
success: success,
|
|
||||||
failure: failure
|
|
||||||
}.merge(last_action_run_json)
|
|
||||||
end
|
|
||||||
render :json => {data: @result}
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
|
@ -1,60 +0,0 @@
|
||||||
class Api::Pm::BaseController < ApplicationController
|
|
||||||
|
|
||||||
include Api::ProjectHelper
|
|
||||||
include Api::UserHelper
|
|
||||||
include Api::PullHelper
|
|
||||||
|
|
||||||
# before_action :doorkeeper_authorize!
|
|
||||||
# skip_before_action :user_setup
|
|
||||||
|
|
||||||
protected
|
|
||||||
|
|
||||||
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 load_project
|
|
||||||
@project = Project.find_by_id(params[:project_id]) || Project.new(id: 0, user_id: 0, name: 'pm_mm', identifier: 'pm_mm', is_public:true)
|
|
||||||
end
|
|
||||||
|
|
||||||
def load_issue
|
|
||||||
# return render_parameter_missing if params[:pm_project_id].blank?
|
|
||||||
@issue = Issue.issue_issue.find_by_id(params[:issue_id])
|
|
||||||
render_not_found('疑修不存在!') if @issue.blank?
|
|
||||||
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_public_and_member_above
|
|
||||||
@project = load_project
|
|
||||||
return render_forbidden if !@project.is_public && !current_user.admin? && !@project.member?(current_user)
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,138 +0,0 @@
|
||||||
class Api::Pm::DashboardsController < Api::Pm::BaseController
|
|
||||||
before_action :require_login
|
|
||||||
def index
|
|
||||||
end
|
|
||||||
|
|
||||||
def todo
|
|
||||||
return render_error('请输入正确的pm_project_ids.') if params[:pm_project_ids].blank?
|
|
||||||
pm_project_ids = params[:pm_project_ids].split(",") rescue []
|
|
||||||
date = params[:date].present? ? params[:date].to_date : Date.today rescue Date.today
|
|
||||||
@issues = Issue.where("start_date <= ? and due_date >= ?", date, date)
|
|
||||||
@issues = @issues.where(pm_project_id: pm_project_ids).joins(:issue_participants).where(issue_participants: {participant_id: current_user.id, participant_type: 'assigned'})
|
|
||||||
@issues = @issues.where.not(status_id: 5)
|
|
||||||
@issues = kaminari_paginate(@issues.distinct.pm_includes)
|
|
||||||
end
|
|
||||||
|
|
||||||
def my_issues
|
|
||||||
return render_error('请输入正确的pm_project_ids.') if params[:pm_project_ids].blank?
|
|
||||||
return render_error('请输入正确的pm_issue_types.') if params[:pm_issue_types].blank?
|
|
||||||
pm_project_ids = params[:pm_project_ids].split(",") rescue []
|
|
||||||
pm_issue_types = params[:pm_issue_types].split(",") rescue []
|
|
||||||
@all_issues = Issue.where(pm_project_id: pm_project_ids, pm_issue_type: pm_issue_types)
|
|
||||||
@issues = @all_issues.joins(:issue_participants).where(issue_participants: {participant_id: current_user.id, participant_type: 'assigned'})
|
|
||||||
@issues = @issues.where.not(status_id: 5) if params[:category] == "opened"
|
|
||||||
|
|
||||||
@issues = kaminari_paginate(@issues.distinct.pm_includes)
|
|
||||||
@my_assign_requirements_count = @all_issues.where(pm_issue_type: 1).joins(:issue_participants).where(issue_participants: {participant_id: current_user.id, participant_type: 'assigned'}).size
|
|
||||||
@my_assign_tasks_count = @all_issues.where(pm_issue_type: 2).joins(:issue_participants).where(issue_participants: {participant_id: current_user.id, participant_type: 'assigned'}).size
|
|
||||||
@my_assign_bugs_count = @all_issues.where(pm_issue_type: 3).joins(:issue_participants).where(issue_participants: {participant_id: current_user.id, participant_type: 'assigned'}).size
|
|
||||||
end
|
|
||||||
|
|
||||||
def my_pm_projects
|
|
||||||
return render_error('请输入正确的pm_project_id.') if params[:pm_project_id].blank?
|
|
||||||
@all_issues = Issue.where(pm_project_id: params[:pm_project_id])
|
|
||||||
time_now = Time.now
|
|
||||||
@last_week_create_issues_count = @all_issues.where("created_on > ? and created_on < ?", time_now - 7.days, time_now).size
|
|
||||||
@before_last_week_create_issue_count = @all_issues.where("created_on > ? and created_on < ?", time_now - 14.days, time_now - 7.days).size
|
|
||||||
@compare_last_week_create_issues = @before_last_week_create_issue_count.zero? ? 0 :(@last_week_create_issues_count - @before_last_week_create_issue_count).to_f / @before_last_week_create_issue_count rescue 0
|
|
||||||
@last_week_close_issues_count = @all_issues.where(status_id: 5).where("updated_on > ? and updated_on < ?", time_now - 7.days, time_now).size
|
|
||||||
@before_last_week_close_issue_count = @all_issues.where(status_id: 5).where("updated_on > ? and updated_on < ?", time_now - 14.days, time_now - 7.days).size
|
|
||||||
@compare_last_week_close_issues = @before_last_week_close_issue_count.zero? ? 0 :(@last_week_close_issues_count - @before_last_week_close_issue_count).to_f / @before_last_week_close_issue_count rescue 0
|
|
||||||
@all_requirement_issues_count = @all_issues.where(pm_issue_type: 1).size
|
|
||||||
@open_requirement_issues_count = @all_issues.where(pm_issue_type: 1).where.not(status_id: 5).size
|
|
||||||
@last_week_close_requirement_issues_count = @all_issues.where(pm_issue_type: 1).where(status_id: 5).where("updated_on > ? and updated_on < ?", time_now - 7.days, time_now).size
|
|
||||||
@last_month_close_requirement_issues_count = @all_issues.where(pm_issue_type: 1).where(status_id: 5).where("updated_on > ? and updated_on < ?", time_now - 30.days, time_now).size
|
|
||||||
@all_task_issues_count = @all_issues.where(pm_issue_type: 2).size
|
|
||||||
@open_task_issues_count = @all_issues.where(pm_issue_type: 2).where.not(status_id: 5).size
|
|
||||||
@last_week_close_tast_issues_count = @all_issues.where(pm_issue_type: 2).where(status_id: 5).where("updated_on > ? and updated_on < ?", time_now - 7.days, time_now).size
|
|
||||||
@last_month_close_task_issues_count = @all_issues.where(pm_issue_type: 2).where(status_id: 5).where("updated_on > ? and updated_on < ?", time_now - 30.days, time_now).size
|
|
||||||
@all_bug_issues_count = @all_issues.where(pm_issue_type: 3).size
|
|
||||||
@open_bug_issues_count = @all_issues.where(pm_issue_type: 3).where.not(status_id: 5).size
|
|
||||||
@last_week_close_bug_issues_count = @all_issues.where(pm_issue_type: 3).where(status_id: 5).where("updated_on > ? and updated_on < ?", time_now - 7.days, time_now).size
|
|
||||||
@last_month_close_bug_issues_count = @all_issues.where(pm_issue_type: 3).where(status_id: 5).where("updated_on > ? and updated_on < ?", time_now - 30.days, time_now).size
|
|
||||||
|
|
||||||
|
|
||||||
@requirement_close_trend = [[],[]]
|
|
||||||
@task_close_trend = [[],[]]
|
|
||||||
@bug_close_trend = [[],[]]
|
|
||||||
((time_now-29.days).to_date..time_now.to_date).to_a.each do |i|
|
|
||||||
@requirement_close_trend[0] << i.strftime("%Y.%m.%d")
|
|
||||||
@task_close_trend[0] << i.strftime("%Y.%m.%d")
|
|
||||||
@bug_close_trend[0] << i.strftime("%Y.%m.%d")
|
|
||||||
@requirement_close_trend[1] << @all_issues.where(pm_issue_type: 1, status_id: 5).where("DATE(updated_on) = ?", i).size
|
|
||||||
@task_close_trend[1] << @all_issues.where(pm_issue_type: 2, status_id: 5).where("DATE(updated_on) = ?", i).size
|
|
||||||
@bug_close_trend[1] << @all_issues.where(pm_issue_type: 3, status_id: 5).where("DATE(updated_on) = ?", i).size
|
|
||||||
end
|
|
||||||
@close_trend = {requirement: @requirement_close_trend, task: @task_close_trend, bug: @bug_close_trend}
|
|
||||||
|
|
||||||
render_ok(data: {
|
|
||||||
last_week_close_issues_count: @last_week_close_issues_count,
|
|
||||||
before_last_week_close_issue_count: @before_last_week_close_issue_count,
|
|
||||||
compare_last_week_close_issues: @compare_last_week_close_issues,
|
|
||||||
last_week_create_issues_count: @last_week_create_issues_count,
|
|
||||||
before_last_week_create_issue_count: @before_last_week_create_issue_count,
|
|
||||||
compare_last_week_create_issues: @compare_last_week_create_issues,
|
|
||||||
all_requirement_issues_count: @all_requirement_issues_count,
|
|
||||||
open_requirement_issues_count: @open_requirement_issues_count,
|
|
||||||
last_week_close_requirement_issues_count: @last_week_close_requirement_issues_count,
|
|
||||||
last_month_close_requirement_issues_count: @last_month_close_requirement_issues_count,
|
|
||||||
all_task_issues_count: @all_task_issues_count,
|
|
||||||
open_task_issues_count: @open_task_issues_count,
|
|
||||||
last_week_close_task_issues_count: @last_week_close_tast_issues_count,
|
|
||||||
last_month_close_task_issues_count: @last_month_close_task_issues_count,
|
|
||||||
all_bug_issues_count: @all_bug_issues_count,
|
|
||||||
open_bug_issues_count: @open_bug_issues_count,
|
|
||||||
last_week_close_bug_issues_count: @last_week_close_bug_issues_count,
|
|
||||||
last_month_close_bug_issues_count: @last_month_close_bug_issues_count,
|
|
||||||
close_trend: @close_trend
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
def my_projects
|
|
||||||
return render_error('请输入正确的project_id.') if params[:project_id].blank?
|
|
||||||
|
|
||||||
@project = Project.find_by_id params[:project_id]
|
|
||||||
return render_error('请输入正确的project_id.') unless @project.present?
|
|
||||||
time_now = Time.now
|
|
||||||
|
|
||||||
branch_tag_result = $gitea_hat_client.get_repos_branch_tag_count_by_owner_repo(@project&.owner&.login, @project&.identifier) rescue {}
|
|
||||||
languages_result = $gitea_client.get_repos_languages_by_owner_repo(@project&.owner&.login, @project&.identifier) rescue {}
|
|
||||||
|
|
||||||
@open_pull_requests_count = @project.pull_requests.opening.size
|
|
||||||
@last_week_close_pull_requests_count = @project.pull_requests.where(status: 1).where("updated_at > ? and updated_at < ?", time_now - 7.days, time_now).size
|
|
||||||
@last_month_close_pull_requets_count = @project.pull_requests.where(status: 1).where("updated_at > ? and updated_at < ?", time_now - 30.days, time_now).size
|
|
||||||
|
|
||||||
@commits_count = @project.commit_logs.size
|
|
||||||
@last_week_commits_count = @project.commit_logs.where("created_at > ? and created_at < ?", time_now - 7.days, time_now).size
|
|
||||||
@last_month_commits_count = @project.commit_logs.where("created_at > ? and created_at < ?", time_now - 30.days, time_now).size
|
|
||||||
|
|
||||||
render_ok(data: {
|
|
||||||
branch_count: branch_tag_result["branch_count"].to_i,
|
|
||||||
tag_count: branch_tag_result["tag_count"].to_i,
|
|
||||||
license_name: @project.license&.name,
|
|
||||||
open_pull_requests_count: @open_pull_requests_count,
|
|
||||||
last_week_close_pull_requests_count: @last_week_close_pull_requests_count,
|
|
||||||
last_month_close_pull_requets_count: @last_month_close_pull_requets_count,
|
|
||||||
commits_count: @commits_count,
|
|
||||||
last_week_commits_count: @last_week_commits_count,
|
|
||||||
last_month_commits_count: @last_month_commits_count,
|
|
||||||
language: hash_transform_precentagable(languages_result),
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
def my_operate_journals
|
|
||||||
return render_error('请输入正确的pm_project_id.') if params[:pm_project_id].blank?
|
|
||||||
@journals = Journal.operate_journals.joins(:issue).where(issues: {pm_project_id: params[:pm_project_id], pm_issue_type: [1,2,3]})
|
|
||||||
|
|
||||||
@journals = kaminari_paginate(@journals.order(updated_on: :desc))
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
def hash_transform_precentagable(hash)
|
|
||||||
total_byte_size = hash.values.sum
|
|
||||||
hash.transform_values { |v|
|
|
||||||
ActionController::Base.helpers
|
|
||||||
.number_to_percentage((v * 100.0 / total_byte_size), precision: 1)
|
|
||||||
}.select{|k,v| v != "0.0%"}
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,46 +0,0 @@
|
||||||
class Api::Pm::IssueLinksController < Api::Pm::BaseController
|
|
||||||
before_action :load_project
|
|
||||||
before_action :load_issue
|
|
||||||
def index
|
|
||||||
@links = PmLink.where(be_linkable_id: @issue.id,be_linkable_type: 'Issue').or(PmLink.where(linkable_id: @issue.id,linkable_type: 'Issue'))
|
|
||||||
end
|
|
||||||
|
|
||||||
def create
|
|
||||||
begin
|
|
||||||
ActiveRecord::Base.transaction do
|
|
||||||
params[:link_ids].each do |e|
|
|
||||||
@issue.pm_links.find_or_create_by!(be_linkable_type: 'Issue', be_linkable_id: e)
|
|
||||||
tag_issue = Issue.find_by_id(e)
|
|
||||||
next unless tag_issue.present?
|
|
||||||
journal = tag_issue.journals.create!({user_id: current_user.id})
|
|
||||||
journal.journal_details.create!({property: "tag_link_issue", prop_key: "1", value: @issue.id.to_s})
|
|
||||||
end
|
|
||||||
journal = @issue.journals.create!({user_id: current_user.id})
|
|
||||||
journal.journal_details.create!({property: "tag_link_issue", prop_key: "#{params[:link_ids].size}", value: params[:link_ids].join(",")})
|
|
||||||
end
|
|
||||||
render_ok
|
|
||||||
rescue
|
|
||||||
render_error('创建失败!')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def destroy
|
|
||||||
begin
|
|
||||||
ActiveRecord::Base.transaction do
|
|
||||||
@links = PmLink.where(be_linkable_id: @issue.id, be_linkable_type: 'Issue', linkable_id: params[:id], linkable_type: 'Issue').or(PmLink.where(linkable_id: @issue.id, linkable_type: 'Issue', be_linkable_id: params[:id], be_linkable_type: 'Issue'))
|
|
||||||
journal = @issue.journals.create!({user_id: current_user.id})
|
|
||||||
journal.journal_details.create!({property: "tag_link_issue", prop_key: "1", old_value: params[:id].to_s})
|
|
||||||
another_issue = Issue.find_by_id(params[:id])
|
|
||||||
if another_issue.present?
|
|
||||||
journal = another_issue.journals.create!({user_id: current_user.id})
|
|
||||||
journal.journal_details.create!({property: "tag_link_issue", prop_key: "1", old_value: @issue.id.to_s})
|
|
||||||
end
|
|
||||||
@link = @links.last
|
|
||||||
@link.destroy!
|
|
||||||
end
|
|
||||||
render_ok
|
|
||||||
rescue
|
|
||||||
render_error('删除失败!')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,71 +0,0 @@
|
||||||
class Api::Pm::IssueTagsController < Api::Pm::BaseController
|
|
||||||
|
|
||||||
def index
|
|
||||||
@issue_tags = IssueTag.pm_able
|
|
||||||
if params[:organization_id].present?
|
|
||||||
IssueTag.pm_org_init_data(params[:organization_id]) unless $redis_cache.hget("pm_org_init_issue_tags", params[:organization_id])
|
|
||||||
@issue_tags = @issue_tags.where(organization_id: params[:organization_id])
|
|
||||||
end
|
|
||||||
@issue_tags = @issue_tags.where(pm_project_id: params[:pm_project_id]) if params[:pm_project_id].present?
|
|
||||||
@issue_tags = @issue_tags.ransack(name_cont: params[:keyword]).result if params[:keyword].present?
|
|
||||||
@issue_tags = @issue_tags.reorder("#{tag_sort_by} #{tag_sort_direction}")
|
|
||||||
@issue_tags = kaminari_paginate(@issue_tags)
|
|
||||||
render "api/v1/issues/issue_tags/index"
|
|
||||||
end
|
|
||||||
|
|
||||||
def create
|
|
||||||
return render_error("请输入正确的OrganizationID") unless Organization.exists?(id: issue_tag_create_params[:organization_id])
|
|
||||||
return render_error("项目标记名称不能为空!") unless issue_tag_create_params[:name].present?
|
|
||||||
@issue_tag = IssueTag.new(issue_tag_create_params.merge!(project_id: 0))
|
|
||||||
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_update_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 tag_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 tag_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_create_params
|
|
||||||
params.permit(:name, :description, :color, :pm_project_id, :organization_id)
|
|
||||||
end
|
|
||||||
|
|
||||||
def issue_tag_update_params
|
|
||||||
params.permit(:name, :description, :color)
|
|
||||||
end
|
|
||||||
|
|
||||||
def load_issue_tag
|
|
||||||
@issue_tag = IssueTag.pm_able.find_by_id(params[:id])
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,376 +0,0 @@
|
||||||
class Api::Pm::IssuesController < Api::Pm::BaseController
|
|
||||||
before_action :require_login, except: [:index]
|
|
||||||
before_action :load_project
|
|
||||||
before_action :load_issue, only: %i[show update destroy link_index link_issues parent_issues]
|
|
||||||
before_action :load_issues, only: %i[batch_update batch_destroy]
|
|
||||||
before_action :check_issue_operate_permission, only: %i[update destroy]
|
|
||||||
|
|
||||||
def index
|
|
||||||
@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]
|
|
||||||
@complete_issues_count = @object_result[:complete_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
|
|
||||||
render 'api/v1/issues/index'
|
|
||||||
end
|
|
||||||
|
|
||||||
def link_index
|
|
||||||
pm_issue_type = params[:pm_issue_type] || [1, 2, 3]
|
|
||||||
not_join_id = case params[:issue_filter_type]
|
|
||||||
when 'leaf_issue'
|
|
||||||
Issue.where(root_id: @issue.id).pluck(:id)
|
|
||||||
when 'link_issue'
|
|
||||||
@issue.pm_links.pluck(:be_linkable_id)
|
|
||||||
end
|
|
||||||
|
|
||||||
not_join_id << @issue.id
|
|
||||||
object_issues = Issue.where(
|
|
||||||
pm_project_id: params[:pm_project_id],
|
|
||||||
pm_issue_type: pm_issue_type
|
|
||||||
).where.not(id: not_join_id).order(updated_on: :desc)
|
|
||||||
|
|
||||||
object_issues = object_issues.where(root_id: nil, child_count: 0) if params[:issue_filter_type] == 'leaf_issue'
|
|
||||||
@issues = kaminari_paginate(object_issues)
|
|
||||||
render 'api/v1/issues/index'
|
|
||||||
end
|
|
||||||
|
|
||||||
def parent_issues
|
|
||||||
@issues = Issue.where(pm_project_id: params[:pm_project_id])
|
|
||||||
.where.not(id: @issue.id)
|
|
||||||
.where.not(id: Issue.full_children_issues(@issue).map{|i|i.id})
|
|
||||||
@issues = @issues.where(pm_issue_type: params[:pm_issue_type]) if params[:pm_issue_type].present?
|
|
||||||
@issues = @issues.ransack(id_or_project_issues_index_eq: params[:keyword]).result.or(@issues.ransack(subject_or_description_cont: params[:keyword]).result) if params[:keyword].present?
|
|
||||||
@issues = @issues.reorder("#{issue_sort_by} #{issue_sort_direction}")
|
|
||||||
if params[:only_name].present?
|
|
||||||
@issues = kaminary_select_paginate(
|
|
||||||
@issues.select(:id, :subject, :project_issues_index, :updated_on, :created_on))
|
|
||||||
else
|
|
||||||
@issues = @issues.includes(:priority, :issue_status, :user, :show_assigners, :show_issue_tags, :version, :comment_journals)
|
|
||||||
@issues = kaminari_paginate(@issues)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def show
|
|
||||||
@issue.associate_attachment_container
|
|
||||||
render 'api/v1/issues/show'
|
|
||||||
end
|
|
||||||
|
|
||||||
def create
|
|
||||||
@object_result = Api::Pm::Issues::CreateService.call(@project, issue_params, current_user)
|
|
||||||
render 'api/v1/issues/create'
|
|
||||||
end
|
|
||||||
|
|
||||||
def update
|
|
||||||
@object_result = Api::Pm::Issues::UpdateService.call(@project, @issue, issue_params, current_user)
|
|
||||||
render 'api/v1/issues/update'
|
|
||||||
end
|
|
||||||
|
|
||||||
def batch_update
|
|
||||||
@object_result = Api::Pm::Issues::BatchUpdateService.call(@project, @issues, batch_issue_params, current_user)
|
|
||||||
if @object_result
|
|
||||||
render_ok
|
|
||||||
else
|
|
||||||
render_error('批量更新疑修失败!')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def batch_destroy
|
|
||||||
return render_ok if params[:ids].is_a?(Array) && params[:ids].blank?
|
|
||||||
@object_result = Api::Pm::Issues::BatchDeleteService.call(@project, @issues, current_user)
|
|
||||||
if @object_result
|
|
||||||
render_ok
|
|
||||||
else
|
|
||||||
render_error('批量删除疑修失败!')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def priorities
|
|
||||||
@priorities = IssuePriority.order(position: :asc)
|
|
||||||
@priorities = @priorities.ransack(name_cont: params[:keyword]).result if params[:keyword]
|
|
||||||
@priorities = kaminary_select_paginate(@priorities)
|
|
||||||
render "api/v1/issues/issue_priorities/index"
|
|
||||||
end
|
|
||||||
|
|
||||||
def tags
|
|
||||||
# IssueTag.pm_init_data(params[:pm_project_id]) unless $redis_cache.hget("pm_project_init_issue_tags", params[:pm_project_id])
|
|
||||||
@issue_tags = IssueTag.where(pm_project_id: params[:pm_project_id]).reorder("#{tag_sort_by} #{tag_sort_direction}")
|
|
||||||
@issue_tags = @issue_tags.ransack(name_cont: params[:keyword]).result if params[:keyword].present?
|
|
||||||
params[:only_name] = true #强制渲染 不走project
|
|
||||||
@issue_tags = kaminary_select_paginate(@issue_tags.select(:id, :name, :color))
|
|
||||||
render "api/v1/issues/issue_tags/index"
|
|
||||||
end
|
|
||||||
|
|
||||||
def statues
|
|
||||||
@statues = IssueStatus.order("position asc")
|
|
||||||
@statues = @statues.ransack(name_cont: params[:keyword]).result if params[:keyword].present?
|
|
||||||
@statues = kaminary_select_paginate(@statues)
|
|
||||||
render "api/v1/issues/statues/index"
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def destroy
|
|
||||||
@object_result = Api::Pm::Issues::DeleteService.call(@project, @issue, current_user)
|
|
||||||
if @object_result
|
|
||||||
render_ok
|
|
||||||
else
|
|
||||||
render_error('删除疑修失败!')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def export
|
|
||||||
return render_error('请输入正确的项目ID.') if params[:pm_project_id].blank?
|
|
||||||
Axlsx::Package.new do |p|
|
|
||||||
[['requirement', 1], ['task', 2], ['bug', 3]].each do |type|
|
|
||||||
p.workbook.add_worksheet(:name => type[0]) do |sheet|
|
|
||||||
@issues = Issue.where(pm_project_id: params[:pm_project_id], pm_issue_type: type[1])
|
|
||||||
sheet.add_row ["ID", "标题*", "正文", "创建者*", "创建时间", "修改者", "更新时间", "状态", "负责人", "优先级", "标记", "开始时间","结束时间", "预估工时"]
|
|
||||||
@issues.each do |issue|
|
|
||||||
sheet.add_row [issue.id, issue.subject, issue.description, issue.user.try(:login), issue.created_on.strftime("%Y-%m-%d %H:%M:%S"), issue.changer.try(:login), issue.updated_on.strftime("%Y-%m-%d %H:%M:%S"), issue.status_id, issue.assigners.pluck(:login).join(","), issue.priority_id, issue.issue_tags.pluck(:name, :color).join(","), issue.start_date.present? ? issue.start_date.strftime("%Y-%m-%d") : "", issue.due_date.present? ? issue.due_date.strftime("%Y-%m-%d") : "", issue.time_scale]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
p.workbook.add_worksheet(:name => 'leaf_relations') do |sheet|
|
|
||||||
leaf_issues = Issue.where(pm_project_id: params[:pm_project_id]).where.not(root_id: nil)
|
|
||||||
sheet.add_row ["ID", "父工作项ID"]
|
|
||||||
leaf_issues.each do |issue|
|
|
||||||
sheet.add_row [issue.id, issue.root_id]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
p.workbook.add_worksheet(:name => 'link_relations') do |sheet|
|
|
||||||
# links = PmLink.joins(:linkable_issue).where(issues: {pm_project_id: params[:pm_project_id]})
|
|
||||||
links = PmLink.find_by_sql("SELECT `pm_links`.* FROM `pm_links` INNER JOIN `issues` ON `issues`.`id` = `pm_links`.`linkable_id` AND `pm_links`.`linkable_type` = 'Issue' WHERE `issues`.`pm_project_id` = #{params[:pm_project_id]}")
|
|
||||||
sheet.add_row ["ID", "被关联工作项ID"]
|
|
||||||
links.each do |link|
|
|
||||||
sheet.add_row [link.linkable_id, link.be_linkable_id]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
p.serialize('public/导出工作项.xlsx')
|
|
||||||
end
|
|
||||||
|
|
||||||
send_file('public/导出工作项.xlsx', :type => 'application/octet-stream;charset=utf-8')
|
|
||||||
end
|
|
||||||
|
|
||||||
def import
|
|
||||||
begin
|
|
||||||
return render_error('请上传正确的文件') if params[:file].blank? || !params[:file].is_a?(ActionDispatch::Http::UploadedFile)
|
|
||||||
return render_error('请输入正确的项目ID.') if params[:pm_project_id].blank?
|
|
||||||
return render_error('请输入正确的组织ID.') if params[:organization_id].blank?
|
|
||||||
ActiveRecord::Base.transaction do
|
|
||||||
types = {requirement: 1, task: 2, bug: 3}
|
|
||||||
doc = SimpleXlsxReader.open(params[:file].tempfile)
|
|
||||||
doc.sheets.each do |sheet|
|
|
||||||
case sheet.name
|
|
||||||
when 'requirement', 'task', 'bug'
|
|
||||||
|
|
||||||
type = types["#{sheet.name}".to_sym]
|
|
||||||
|
|
||||||
sheet.rows.each.with_index do |row, index|
|
|
||||||
next if index == 0
|
|
||||||
issue = Issue.new(issue_classify: "issue", project_id: 0, pm_project_id: params[:pm_project_id], pm_issue_type: type, tracker_id: Tracker.first.id)
|
|
||||||
issue.fake_id = row[0]
|
|
||||||
issue.subject = row[1]
|
|
||||||
issue.description = row[2]
|
|
||||||
author = User.find_by(login: row[3])
|
|
||||||
issue.user = author
|
|
||||||
issue.created_on = row[4]
|
|
||||||
changer = User.find_by(login: row[5])
|
|
||||||
issue.changer = changer
|
|
||||||
issue.updated_on = row[6]
|
|
||||||
issue.status_id = row[7].to_i
|
|
||||||
if row[8].present?
|
|
||||||
row[8].split(',').each do |a|
|
|
||||||
u = User.find_by(login: a)
|
|
||||||
next unless u.present?
|
|
||||||
issue.assigners << u
|
|
||||||
end
|
|
||||||
end
|
|
||||||
issue.priority_id = row[9]
|
|
||||||
if row[10].present?
|
|
||||||
row[10].split(',').each_slice(2).to_a.each do |t|
|
|
||||||
tag = IssueTag.find_by(project_id: 0, organization_id: params[:organization_id], name: t[0])
|
|
||||||
if tag.present?
|
|
||||||
issue.issue_tags << tag
|
|
||||||
else
|
|
||||||
tag = IssueTag.create(project_id: 0,organization_id: params[:organization_id], name: t[0], color: t[1])
|
|
||||||
issue.issue_tags << tag
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
issue.start_date = row[11]
|
|
||||||
issue.due_date = row[12]
|
|
||||||
issue.time_scale = row[13]
|
|
||||||
issue.save!
|
|
||||||
end
|
|
||||||
when 'leaf_relations'
|
|
||||||
sheet.rows.each.with_index do |row, index|
|
|
||||||
next if index == 0
|
|
||||||
children_issue = Issue.where(fake_id: row[0]).last
|
|
||||||
parent_issue = Issue.where(fake_id: row[1]).last
|
|
||||||
next if children_issue.blank? || parent_issue.blank?
|
|
||||||
children_issue.root_id = parent_issue.id
|
|
||||||
children_issue.save(touch: false)
|
|
||||||
end
|
|
||||||
when 'link_relations'
|
|
||||||
sheet.rows.each.with_index do |row, index|
|
|
||||||
next if index == 0
|
|
||||||
link_issue = Issue.where(fake_id: row[0]).last
|
|
||||||
be_link_issue = Issue.where(fake_id: row[1]).last
|
|
||||||
next if link_issue.blank? || be_link_issue.blank?
|
|
||||||
PmLink.create!(linkable_type: 'Issue', linkable_id: link_issue.id, be_linkable_type: 'Issue', be_linkable_id: be_link_issue.id)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
return render_error('导入失败,请上传正确格式的excel文件')
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
||||||
render_ok
|
|
||||||
rescue
|
|
||||||
return render_error('导入失败,请上传正确格式的excel文件')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def link_issues
|
|
||||||
children_issues = @issue.pm_issue_type == 1 ? @issue.child_count > 0 ? Issue.where(id: @issue.id) : Issue.none : Issue.where(root_id: @issue.id)
|
|
||||||
linkable_issues = Issue.where(id: PmLink.where(linkable_type: "Issue", linkable_id: @issue.id).pluck(:be_linkable_id))
|
|
||||||
belinkable_issues = Issue.where(id: PmLink.where(be_linkable_type: "Issue", be_linkable_id: @issue.id).pluck(:linkable_id))
|
|
||||||
|
|
||||||
full_link_issues_ids = children_issues.pluck(:id) | linkable_issues.pluck(:id) | belinkable_issues.pluck(:id)
|
|
||||||
compare_link_issues_ids = children_issues.pluck(:id) | linkable_issues.pluck(:id) | belinkable_issues.pluck(:id)
|
|
||||||
i = compare_link_issues_ids.count
|
|
||||||
while i > 0 do
|
|
||||||
children_issues = Issue.where(root_id: compare_link_issues_ids)
|
|
||||||
linkable_issues = Issue.where(id: PmLink.where(linkable_type: "Issue", linkable_id: compare_link_issues_ids).pluck(:be_linkable_id))
|
|
||||||
belinkable_issues = Issue.where(id: PmLink.where(be_linkable_type: "Issue", be_linkable_id: compare_link_issues_ids).pluck(:linkable_id))
|
|
||||||
|
|
||||||
compare_link_issues_ids = (children_issues.pluck(:id) | linkable_issues.pluck(:id) | belinkable_issues.pluck(:id)) - full_link_issues_ids
|
|
||||||
full_link_issues_ids = full_link_issues_ids | compare_link_issues_ids
|
|
||||||
i = compare_link_issues_ids.count
|
|
||||||
end
|
|
||||||
exclude_issues_ids = []
|
|
||||||
exclude_issues = Issue.where(id: full_link_issues_ids).where.not(root_id: nil)
|
|
||||||
exclude_issues.each do |i|
|
|
||||||
exclude_issues_ids << i.id if i.pm_issue_type == 1 && full_link_issues_ids.include?(i.root_id)
|
|
||||||
end
|
|
||||||
full_link_issues_ids = full_link_issues_ids - exclude_issues_ids
|
|
||||||
@requirement_issues = Issue.where(id:full_link_issues_ids, pm_issue_type:1, root_id: nil).pm_includes
|
|
||||||
@task_issues = Issue.where(id:full_link_issues_ids, pm_issue_type:2).pm_includes
|
|
||||||
@bug_issues = Issue.where(id:full_link_issues_ids, pm_issue_type:3).pm_includes
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
def circle_link_issues(issue_ids)
|
|
||||||
if issue_ids.present?
|
|
||||||
children_issues = Issue.joins(:parent_issue).where(issues: {id: issue_ids})
|
|
||||||
linkable_issues = Issue.where(id: PmLink.where(linkable_type: "Issue", linkable_id: issue_ids))
|
|
||||||
belinkable_issues = Issue.where(id: PmLink.where(be_linkable_type: "Issue", be_linkable_id: issue_ids))
|
|
||||||
|
|
||||||
return circle_link_issues(children_issues.pluck(:id))
|
|
||||||
else
|
|
||||||
return []
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def check_issue_operate_permission
|
|
||||||
return if params[:project_id].to_i.zero?
|
|
||||||
render_forbidden('您没有操作权限!') unless @project.member?(current_user) || current_user.admin? || @issue.user == current_user
|
|
||||||
end
|
|
||||||
|
|
||||||
def load_issue
|
|
||||||
# return render_parameter_missing if params[:pm_project_id].blank?
|
|
||||||
@issue = Issue.issue_issue.find_by_id(params[:id])
|
|
||||||
render_not_found('疑修不存在!') if @issue.blank?
|
|
||||||
end
|
|
||||||
|
|
||||||
# def load_issue_by_index
|
|
||||||
# return render_parameter_missing if params[:pm_project_id].blank? || params[:pm_issue_type].blank? || params[:enterprise_identifier].blank?
|
|
||||||
# @issue = Issue.find_issues_by_pm(params[:enterprise_identifier], params[:pm_issue_type])
|
|
||||||
# .find_by(pm_issue_type_index3: params[:index])
|
|
||||||
# render_not_found('疑修不存在!') if @issue.blank?
|
|
||||||
# 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, pm_project_id: params[:pm_project_id])
|
|
||||||
return render_not_found("ID为#{id}的疑修不存在!") if @issue.blank?
|
|
||||||
end
|
|
||||||
if params[:ids].blank?
|
|
||||||
@issues = Issue.where(pm_project_id: params[:pm_project_id])
|
|
||||||
else
|
|
||||||
@issues = Issue.where(id: params[:ids], pm_project_id: params[:pm_project_id])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
def query_params
|
|
||||||
params.permit(
|
|
||||||
:only_name,
|
|
||||||
:category,
|
|
||||||
:participant_category,
|
|
||||||
:keyword, :author_id,
|
|
||||||
:milestone_id, :assigner_id,
|
|
||||||
:status_id, :priority_id,
|
|
||||||
:begin_date, :end_date,
|
|
||||||
:update_begin_date, :update_end_date,
|
|
||||||
:sort_by, :sort_direction, :root_id,
|
|
||||||
:issue_tag_ids, :pm_project_id, :pm_sprint_id, :pm_issue_type, :pm_project_ids,
|
|
||||||
:status_ids, :ids, :exclude_ids, :pm_issue_types, :participator_id, :enterprise_identifier
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def issue_params
|
|
||||||
params.permit(
|
|
||||||
:status_id, :priority_id, :milestone_id,
|
|
||||||
:branch_name, :start_date, :due_date, :time_scale,
|
|
||||||
:subject, :description, :blockchain_token_num, :root_subject,
|
|
||||||
:pm_project_id, :pm_sprint_id, :pm_issue_type, :root_id, :link_able_id, :project_id,
|
|
||||||
:status_msg, :enterprise_identifier,
|
|
||||||
issue_tag_ids: [],
|
|
||||||
assigner_ids: [],
|
|
||||||
attachment_ids: [],
|
|
||||||
receivers_login: []
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
def batch_issue_params
|
|
||||||
params.permit(
|
|
||||||
:status_id, :priority_id, :milestone_id, :pm_sprint_id, :due_date, :pm_issue_type, :root_id, :target_pm_project_id, :project_id,
|
|
||||||
:issue_tag_ids => [],
|
|
||||||
:assigner_ids => [] )
|
|
||||||
end
|
|
||||||
|
|
||||||
def issue_sort_by
|
|
||||||
sort_by = params.fetch(:sort_by, "updated_on")
|
|
||||||
sort_by = Issue.column_names.include?(sort_by) ? sort_by : "updated_on"
|
|
||||||
sort_by
|
|
||||||
end
|
|
||||||
|
|
||||||
def issue_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 tag_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 tag_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,61 +0,0 @@
|
||||||
class Api::Pm::JournalsController < Api::Pm::BaseController
|
|
||||||
before_action :require_login, except: [:index, :children_journals]
|
|
||||||
before_action :load_project
|
|
||||||
before_action :load_issue
|
|
||||||
before_action :load_journal, only: [:children_journals, :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])
|
|
||||||
render 'api/pm/issues/journals/index'
|
|
||||||
end
|
|
||||||
|
|
||||||
def create
|
|
||||||
@object_result = Api::V1::Issues::Journals::CreateService.call(@issue, journal_params, current_user)
|
|
||||||
render 'api/v1/issues/journals/create'
|
|
||||||
end
|
|
||||||
|
|
||||||
def children_journals
|
|
||||||
@object_results = Api::V1::Issues::Journals::ChildrenListService.call(@issue, @journal, query_params, current_user)
|
|
||||||
@journals = kaminari_paginate(@object_results)
|
|
||||||
render 'api/v1/issues/journals/children_journals'
|
|
||||||
end
|
|
||||||
|
|
||||||
def update
|
|
||||||
@object_result = Api::V1::Issues::Journals::UpdateService.call(@issue, @journal, journal_params, current_user)
|
|
||||||
render 'api/v1/issues/journals/update'
|
|
||||||
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 = Issue.issue_issue.where(pm_project_id: params[:pm_project_id]).find_by_id(params[:issue_id])
|
|
||||||
render_not_found('疑修不存在!') if @issue.blank?
|
|
||||||
end
|
|
||||||
|
|
||||||
def load_journal
|
|
||||||
@journal = Journal.find_by_id(params[:id])
|
|
||||||
render_not_found('评论不存在!') unless @journal.present?
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
|
@ -1,77 +0,0 @@
|
||||||
class Api::Pm::PipelinesController < Api::Pm::BaseController
|
|
||||||
include RepositoriesHelper
|
|
||||||
|
|
||||||
def index
|
|
||||||
@owner = Owner.find_by(login: params[:owner_id].to_s) || Owner.find_by(id: params[:owner_id].to_s)
|
|
||||||
tip_exception('组织未找到') if @owner.blank?
|
|
||||||
unless @owner.is_a?(Organization) && @owner.is_member?(current_user.id)
|
|
||||||
tip_exception('没有查看组织的权限')
|
|
||||||
end
|
|
||||||
@project_ids = @owner.projects.ids
|
|
||||||
project_gpids = @owner.projects.pluck(:gpid)
|
|
||||||
action_runs = Gitea::ActionRun.where(owner_id: @owner.gitea_uid)
|
|
||||||
group_data = action_runs.where(status: [1,2]).group(:workflow_id, :status).count
|
|
||||||
pipelines = Action::Pipeline.where(project_id: @project_ids).order(updated_at: :desc)
|
|
||||||
run_files = Gitea::ActionRun.select(:workflow_id, :repo_id).where(owner_id: @owner.gitea_uid).group(:workflow_id, :repo_id)
|
|
||||||
db_files = pipelines.pluck(:file_name)
|
|
||||||
@run_result = []
|
|
||||||
run_files.each do |file_info|
|
|
||||||
file = file_info.workflow_id
|
|
||||||
project = Project.find_by(gpid: file_info.repo_id)
|
|
||||||
next if project.blank?
|
|
||||||
unless db_files.include?(".gitea/workflows/#{file}")
|
|
||||||
pipeline = Action::Pipeline.find_or_initialize_by(pipeline_name: file.to_s.gsub(".yml", "").gsub(".yaml", ""),
|
|
||||||
file_name: ".gitea/workflows/#{file}",
|
|
||||||
branch: project.default_branch,
|
|
||||||
is_graphic_design: false,
|
|
||||||
disable: false,
|
|
||||||
project_id: project.id)
|
|
||||||
interactor = Repositories::EntriesInteractor.call(@owner, project.identifier, ".gitea/workflows/#{file}", ref: project.default_branch)
|
|
||||||
if interactor.success?
|
|
||||||
pipeline.yaml = decode64_content(interactor.result, @owner, project.repository, project.default_branch, nil)
|
|
||||||
end
|
|
||||||
pipeline.user_id = current_user.id
|
|
||||||
pipeline.save
|
|
||||||
# 导入的流水线统一先禁用
|
|
||||||
$gitea_hat_client.post_repos_actions_disable(project&.owner&.login, project&.identifier, {query: {workflow: file}}) rescue nil
|
|
||||||
end
|
|
||||||
last_action_run = action_runs.where(repo_id: project.gpid).where(workflow_id: file).order(updated: :desc).first
|
|
||||||
last_action_run_json = last_action_run.present? ? {
|
|
||||||
id: last_action_run.id,
|
|
||||||
schedule: last_action_run.schedule_id > 0,
|
|
||||||
title: last_action_run.title,
|
|
||||||
index: last_action_run.index,
|
|
||||||
status: last_action_run.status,
|
|
||||||
started: last_action_run.started,
|
|
||||||
stopped: last_action_run.stopped,
|
|
||||||
length: last_action_run.stopped-last_action_run.started,
|
|
||||||
created: last_action_run.created,
|
|
||||||
updated: last_action_run.updated,
|
|
||||||
} : {}
|
|
||||||
|
|
||||||
total = 0
|
|
||||||
success = 0
|
|
||||||
failure = 0
|
|
||||||
group_data.each do |k,v|
|
|
||||||
total += v if k[0] == file
|
|
||||||
success += v if k[0] == file && k[1] == 1
|
|
||||||
failure += v if k[0] == file && k[1] == 2
|
|
||||||
end
|
|
||||||
@run_result << {
|
|
||||||
repo_id: last_action_run.repo_id,
|
|
||||||
filename: ".gitea/workflows/#{file}",
|
|
||||||
total: total,
|
|
||||||
success: success,
|
|
||||||
failure: failure
|
|
||||||
}.merge(last_action_run_json)
|
|
||||||
end
|
|
||||||
# Rails.logger.info("@run_result======#{@run_result}")
|
|
||||||
@disabled_workflows = Gitea::RepoUnit.where(repo_id: project_gpids, type: 10).where("config is not null")
|
|
||||||
@pipelines = Action::Pipeline.select("distinct project_id,max(updated_at) as updated_at")
|
|
||||||
.where(project_id: @project_ids).group(:project_id).order("updated_at desc")
|
|
||||||
@pipelines = @pipelines.where("pipeline_name like ?", "%#{params[:pipeline_name]}%") if params[:pipeline_name].present?
|
|
||||||
@pipelines = @pipelines.where(pipeline_type: params[:pipeline_type]) if params[:pipeline_type].present?
|
|
||||||
@pipelines = kaminari_paginate(@pipelines)
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
|
@ -1,156 +0,0 @@
|
||||||
class Api::Pm::ProjectsController < Api::Pm::BaseController
|
|
||||||
before_action :require_login, except: [:convert]
|
|
||||||
before_action :load_project, only: [:convert]
|
|
||||||
def convert
|
|
||||||
data = {
|
|
||||||
owner: @project.owner.try(:login),
|
|
||||||
identifier: @project.identifier,
|
|
||||||
name: @project.name
|
|
||||||
}
|
|
||||||
render_ok(data: data)
|
|
||||||
end
|
|
||||||
|
|
||||||
def issues_count
|
|
||||||
return tip_exception '参数错误' unless params[:pm_project_id].present?
|
|
||||||
@issues = Issue.where(pm_project_id: params[:pm_project_id])
|
|
||||||
case params[:category].to_s
|
|
||||||
when 'closed'
|
|
||||||
@issues = @issues.closed
|
|
||||||
when 'opened'
|
|
||||||
@issues = @issues.opened
|
|
||||||
end
|
|
||||||
@participant_category_count = {}
|
|
||||||
if params[:participant_category].to_s == "authoredme" or params[:participant_category].to_s == "assignedme"
|
|
||||||
issues_category = @issues.joins(:issue_participants).where(pm_issue_type: [1, 2, 3]).where(issue_participants: {participant_type: %w[authored assigned atme], participant_id: current_user&.id})
|
|
||||||
@participant_category_count = issues_category.group(:pm_project_id, "issue_participants.participant_type").count
|
|
||||||
end
|
|
||||||
case params[:participant_category].to_s
|
|
||||||
when 'aboutme' # 关于我的
|
|
||||||
@issues = @issues.joins(:issue_participants).where(issue_participants: {participant_type: %w[authored assigned atme], participant_id: current_user&.id})
|
|
||||||
when 'authoredme' # 我创建的
|
|
||||||
@issues = @issues.joins(:issue_participants).where(issue_participants: {participant_type: 'authored', participant_id: current_user&.id})
|
|
||||||
when 'assignedme' # 我负责的
|
|
||||||
@issues = @issues.joins(:issue_participants).where(issue_participants: {participant_type: 'assigned', participant_id: current_user&.id})
|
|
||||||
when 'atme' # @我的
|
|
||||||
@issues = @issues.joins(:issue_participants).where(issue_participants: {participant_type: 'atme', participant_id: current_user&.id})
|
|
||||||
end
|
|
||||||
data = {}
|
|
||||||
@issues_count = @issues.group(:pm_project_id).count
|
|
||||||
# requirement 1 task 2 bug 3
|
|
||||||
@issues_type_count = @issues.group(:pm_project_id, :pm_issue_type).count
|
|
||||||
params[:pm_project_id].map(&:to_i).map do |project_id|
|
|
||||||
data[project_id] = {
|
|
||||||
total: @issues_count[project_id] || 0,
|
|
||||||
requirement: @issues_type_count[[project_id, 1]] || 0,
|
|
||||||
task: @issues_type_count[[project_id, 2]] || 0,
|
|
||||||
bug: @issues_type_count[[project_id, 3]] || 0,
|
|
||||||
authoredme: @participant_category_count[[project_id, 0]] || 0,
|
|
||||||
assignedme: @participant_category_count[[project_id, 1]] || 0,
|
|
||||||
atme: @participant_category_count[[project_id, 4]] || 0,
|
|
||||||
}
|
|
||||||
end
|
|
||||||
render_ok(data: data)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
def statistics
|
|
||||||
return tip_exception '参数错误' if params[:pm_project_id].blank?
|
|
||||||
@issues = Issue.where(pm_project_id: params[:pm_project_id], pm_issue_type:[1, 2, 3])
|
|
||||||
@last_week_close_issues = @issues.where(status_id: 5).where("updated_on > ? and updated_on < ?", Time.now - 7.days, Time.now)
|
|
||||||
last_week_close_type_count_data = @last_week_close_issues.group(:pm_issue_type).count
|
|
||||||
type_count_data = @issues.group(:pm_issue_type).count
|
|
||||||
type_status = @issues.group(:pm_issue_type,:status_id).count
|
|
||||||
type_status_data = {}
|
|
||||||
IssueStatus.all.map do |e|
|
|
||||||
# next if e.id == 5
|
|
||||||
[1,2,3].map{ |type|
|
|
||||||
next if type == 1 && [1, 6].include?(e.id)
|
|
||||||
type_status_data[type] = {} if type_status_data[type].nil?
|
|
||||||
if type_status[[type,e.id]].nil?
|
|
||||||
type_status_data[type][e.id] = 0
|
|
||||||
else
|
|
||||||
type_status_data[type][e.id] = type_status[[type,e.id]]
|
|
||||||
end
|
|
||||||
}
|
|
||||||
end
|
|
||||||
open_data = {
|
|
||||||
"1": type_status_data[1][1].to_i + type_status_data[1][2].to_i + type_status_data[1][3].to_i + type_status_data[1][6].to_i,
|
|
||||||
"2": type_status_data[2][1].to_i + type_status_data[2][2].to_i + type_status_data[2][3].to_i + type_status_data[2][6].to_i,
|
|
||||||
"3": type_status_data[3][1].to_i + type_status_data[3][2].to_i + type_status_data[3][3].to_i + type_status_data[3][6].to_i,
|
|
||||||
}
|
|
||||||
if type_count_data.keys.size < 3
|
|
||||||
nedd_add = [1,2,3] - type_count_data.keys
|
|
||||||
nedd_add.map{ |e|
|
|
||||||
type_count_data[e] = 0
|
|
||||||
}
|
|
||||||
end
|
|
||||||
if last_week_close_type_count_data.keys.size < 3
|
|
||||||
nedd_add = [1,2,3] - last_week_close_type_count_data.keys
|
|
||||||
nedd_add.map{ |e|
|
|
||||||
last_week_close_type_count_data[e] = 0
|
|
||||||
}
|
|
||||||
end
|
|
||||||
data = {
|
|
||||||
pie_chart: type_count_data,
|
|
||||||
bar_chart: type_status_data,
|
|
||||||
open_data: open_data,
|
|
||||||
last_week_close_data: last_week_close_type_count_data,
|
|
||||||
}
|
|
||||||
render_ok(data: data)
|
|
||||||
end
|
|
||||||
|
|
||||||
def polyline
|
|
||||||
return tip_exception '参数错误' if params[:pm_project_id].blank?
|
|
||||||
time_line = (Time.current.beginning_of_day - 29.day) .. Time.current
|
|
||||||
@create_issues = Issue.where(pm_project_id: params[:pm_project_id],created_on: time_line)
|
|
||||||
@due_issues = Issue.where(pm_project_id: params[:pm_project_id],status_id:[3,5],due_date: time_line)
|
|
||||||
@create_issues_count = @create_issues.group(:pm_issue_type,"DATE(created_on)").count
|
|
||||||
@due_issues_count = @due_issues.group(:pm_issue_type,"DATE(due_date)").count
|
|
||||||
data = {
|
|
||||||
create_issues: {},
|
|
||||||
due_issues: {}
|
|
||||||
}
|
|
||||||
30.times do |time|
|
|
||||||
current_time = Date.current - time.day
|
|
||||||
if @create_issues_count.present?
|
|
||||||
data[:create_issues][current_time] = {
|
|
||||||
"1": @create_issues_count[[1,current_time]] || 0,
|
|
||||||
"2": @create_issues_count[[2,current_time]] || 0,
|
|
||||||
"3": @create_issues_count[[3,current_time]] || 0
|
|
||||||
}
|
|
||||||
else
|
|
||||||
data[:create_issues][current_time] = {
|
|
||||||
"1": 0,
|
|
||||||
"2": 0,
|
|
||||||
"3": 0
|
|
||||||
}
|
|
||||||
end
|
|
||||||
if @due_issues_count.present?
|
|
||||||
data[:due_issues][current_time] = {
|
|
||||||
"1": @due_issues_count[[1,current_time]] || 0,
|
|
||||||
"2": @due_issues_count[[2,current_time]] || 0,
|
|
||||||
"3": @due_issues_count[[3,current_time]] || 0
|
|
||||||
}
|
|
||||||
else
|
|
||||||
data[:due_issues][current_time] = {
|
|
||||||
"1": 0,
|
|
||||||
"2": 0,
|
|
||||||
"3": 0
|
|
||||||
}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
render_ok(data: data)
|
|
||||||
end
|
|
||||||
|
|
||||||
def bind_project
|
|
||||||
return render_forbidden('您没有操作权限!') unless @project.member?(current_user) || current_user.admin?
|
|
||||||
Issue.where(pm_project_id: params[:pm_project_id], user_id: current_user).update_all(project_id: params[:project_id])
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
def load_project
|
|
||||||
@project = Project.joins(:owner).find params[:project_id]
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
end
|
|
|
@ -1,109 +0,0 @@
|
||||||
class Api::Pm::SprintIssuesController < Api::Pm::BaseController
|
|
||||||
|
|
||||||
before_action :require_login, except: [:index]
|
|
||||||
|
|
||||||
def index
|
|
||||||
@issues = Api::Pm::SprintIssues::ListService.call(query_params, current_user)
|
|
||||||
@issues = kaminari_paginate(@issues)
|
|
||||||
render 'api/v1/issues/index'
|
|
||||||
end
|
|
||||||
|
|
||||||
def burndown_charts
|
|
||||||
return tip_exception '参数错误' if params[:pm_sprint_id].blank? || params[:start_time].blank? || params[:end_time].blank?
|
|
||||||
@issues = Issue.where(pm_sprint_id: params[:pm_sprint_id])
|
|
||||||
start_time = Date.parse params[:start_time]
|
|
||||||
end_time = Date.parse params[:end_time]
|
|
||||||
time_count = (end_time - start_time).to_i + 1 # 计算间隔时间 加上最后一天
|
|
||||||
data = []
|
|
||||||
curren_issues = @issues.group(:status_id, :due_date).count
|
|
||||||
total_count = @issues.count
|
|
||||||
cardinality = (total_count.zero? || time_count.zero?) ? 0 : total_count.to_f / time_count.to_f
|
|
||||||
# cardinality = BigDecimal.new(total_count) / BigDecimal.new(time_count)
|
|
||||||
time_count.times do |x|
|
|
||||||
e_time = start_time + x
|
|
||||||
completed = curren_issues[[5, e_time]].to_i + curren_issues[[3, e_time]].to_i - @issues.where(pm_issue_type: 3, status_id: 3).size
|
|
||||||
total_count = total_count - completed
|
|
||||||
data << { time: e_time, undone: total_count, completed: completed, base_number: (cardinality * (time_count - x - 1)).to_f.round(2) }
|
|
||||||
end
|
|
||||||
render_ok(data: data)
|
|
||||||
end
|
|
||||||
|
|
||||||
def statistics
|
|
||||||
pm_sprint_ids = params[:pm_sprint_ids].split(",") rescue []
|
|
||||||
return tip_exception '参数错误' if pm_sprint_ids.blank?
|
|
||||||
@issues = Issue.where(pm_sprint_id: pm_sprint_ids)
|
|
||||||
data = {}
|
|
||||||
# requirement 1 task 2 bug 3
|
|
||||||
@issues_count = @issues.group(:pm_sprint_id).count
|
|
||||||
@issues_type_count = @issues.group(:pm_sprint_id, :status_id).count
|
|
||||||
@issues_pm_type_count = @issues.group(:pm_sprint_id, :pm_issue_type).count
|
|
||||||
@issues_hour_count = @issues.group(:pm_sprint_id).sum(:time_scale)
|
|
||||||
@issues_hour_type_count = @issues.group(:pm_sprint_id, :status_id).sum(:time_scale)
|
|
||||||
@issues_hour_pm_type_count = @issues.group(:pm_sprint_id, :pm_issue_type).sum(:time_scale)
|
|
||||||
@issues_status_pm_type_count = @issues.group(:pm_sprint_id, :pm_issue_type, :status_id).count
|
|
||||||
pm_sprint_ids.map(&:to_i).map do |sprint_id|
|
|
||||||
# count_closed 工作项已完成/已关闭数量,需排除已修复的缺陷数量
|
|
||||||
count_closed = @issues_type_count[[sprint_id, 5]].to_i + @issues_type_count[[sprint_id, 3]].to_i - @issues.where(pm_sprint_id: sprint_id, pm_issue_type: 3, status_id: 3).size
|
|
||||||
# hour_closed 已完成/已关闭 预估工时之和,需排除已修复的缺陷预估工时
|
|
||||||
hour_closed = @issues_hour_type_count[[sprint_id, 5]].to_f + @issues_hour_type_count[[sprint_id, 3]].to_f - @issues.where(pm_sprint_id: sprint_id, pm_issue_type: 3, status_id: 3).sum(:time_scale).to_f
|
|
||||||
data[sprint_id] = {
|
|
||||||
count_total: @issues_count[sprint_id] || 0,
|
|
||||||
count_closed: count_closed || 0,
|
|
||||||
hour_total: @issues_hour_count[sprint_id].to_f || 0,
|
|
||||||
hour_closed: hour_closed || 0,
|
|
||||||
requirement: @issues_pm_type_count[[sprint_id, 1]] || 0,
|
|
||||||
task: @issues_pm_type_count[[sprint_id, 2]] || 0,
|
|
||||||
bug: @issues_pm_type_count[[sprint_id, 3]] || 0,
|
|
||||||
requirement_hour: @issues_hour_pm_type_count[[sprint_id, 1]].to_i || 0,
|
|
||||||
task_hour: @issues_hour_pm_type_count[[sprint_id, 2]].to_i || 0,
|
|
||||||
bug_hour: @issues_hour_pm_type_count[[sprint_id, 3]].to_i || 0,
|
|
||||||
requirement_open: (@issues_status_pm_type_count[[sprint_id, 1, 1]].to_i + @issues_status_pm_type_count[[sprint_id, 1, 2]].to_i) || 0,
|
|
||||||
task_open: @issues_status_pm_type_count[[sprint_id, 2, 1]].to_i + @issues_status_pm_type_count[[sprint_id, 2, 2]].to_i || 0,
|
|
||||||
bug_open: @issues_status_pm_type_count[[sprint_id, 3, 1]].to_i + @issues_status_pm_type_count[[sprint_id, 3, 2]].to_i || 0
|
|
||||||
}
|
|
||||||
end
|
|
||||||
render_ok(data: data)
|
|
||||||
end
|
|
||||||
|
|
||||||
before_action :load_uncomplete_issues, only: [:complete]
|
|
||||||
|
|
||||||
def complete
|
|
||||||
begin
|
|
||||||
case complete_params[:complete_type].to_i
|
|
||||||
when 1
|
|
||||||
@issues.update_all(status_id: 5, due_date: Time.now)
|
|
||||||
when 2
|
|
||||||
@issues.update_all(pm_sprint_id: 0)
|
|
||||||
when 3
|
|
||||||
@issues.update_all(pm_sprint_id: complete_params[:target_pm_project_sprint_id])
|
|
||||||
end
|
|
||||||
render_ok
|
|
||||||
rescue => e
|
|
||||||
render_error(e.message)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def load_uncomplete_issues
|
|
||||||
@issues = Issue.where(pm_sprint_id: complete_params[:pm_project_sprint_id]).where.not(status_id: 5)
|
|
||||||
end
|
|
||||||
|
|
||||||
def complete_params
|
|
||||||
params.permit(:pm_project_sprint_id, :complete_type, :target_pm_project_sprint_id)
|
|
||||||
end
|
|
||||||
|
|
||||||
def query_params
|
|
||||||
params.permit(
|
|
||||||
:category,
|
|
||||||
:pm_project_id,
|
|
||||||
:pm_issue_type, # 需求1 任务2 缺陷3
|
|
||||||
:assigner_id,
|
|
||||||
:priority_id,
|
|
||||||
:status_id,
|
|
||||||
:keyword, :status_ids, :pm_issue_types,
|
|
||||||
:sort_by, :sort_direction
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
|
@ -1,82 +0,0 @@
|
||||||
class Api::Pm::WeeklyIssuesController < Api::Pm::BaseController
|
|
||||||
|
|
||||||
def personal
|
|
||||||
@enterprise_identifier = params[:enterprise_identifier] || ''
|
|
||||||
return render_error('请输入正确的用户ID.') if params[:user_id].blank?
|
|
||||||
@all_issues = Issue.joins(:issue_participants).where(issue_participants: {participant_id: params[:user_id], participant_type: ['assigned']})
|
|
||||||
@all_issues = @all_issues.where(enterprise_identifier: @enterprise_identifier, pm_issue_type: [1,2,3])
|
|
||||||
@this_week_all_issues = @all_issues.where("due_date >= ? and start_date <= ?", Date.today.beginning_of_week.to_s, Date.today.end_of_week.to_s).distinct
|
|
||||||
@this_week_all_issues = @this_week_all_issues.order('created_on desc')
|
|
||||||
@next_week_all_issues = @all_issues.where("due_date >= ? and start_date <=?", (Date.today.beginning_of_week+1.week).to_s, (Date.today.end_of_week+1.week).to_s).distinct
|
|
||||||
@next_week_all_issues = @next_week_all_issues.order('created_on desc')
|
|
||||||
@this_week_requirement_issues = @this_week_all_issues.where(pm_issue_type: 1)
|
|
||||||
@this_week_task_issues = @this_week_all_issues.where(pm_issue_type: 2)
|
|
||||||
@this_week_bug_issues = @this_week_all_issues.where(pm_issue_type: 3)
|
|
||||||
@close_requirement_issues = @this_week_requirement_issues.where(status_id: [3,5])
|
|
||||||
@close_task_issues = @this_week_task_issues.where(status_id: [3,5])
|
|
||||||
@close_bug_issues = @this_week_bug_issues.where(status_id: [3,5])
|
|
||||||
this_week_page = params[:this_week_page] || 1
|
|
||||||
this_week_limit = params[:this_week_limit] || 15
|
|
||||||
@this_week_all_issues = @this_week_all_issues.page(this_week_page).per(this_week_limit)
|
|
||||||
next_week_page = params[:next_week_page] || 1
|
|
||||||
next_week_limit = params[:next_week_limit] || 15
|
|
||||||
@next_week_all_issues = @next_week_all_issues.page(next_week_page).per(next_week_limit)
|
|
||||||
end
|
|
||||||
|
|
||||||
def group
|
|
||||||
@enterprise_identifier = params[:enterprise_identifier] || ''
|
|
||||||
@all_issues = Issue.where(enterprise_identifier: @enterprise_identifier, pm_issue_type: [1,2,3])
|
|
||||||
@all_issues = @all_issues.where(pm_project_id: params[:pm_project_ids].split(",")) if params[:pm_project_ids].present?
|
|
||||||
@this_week_all_issues = @all_issues.where("due_date >= ? and start_date <= ?", Date.today.beginning_of_week.to_s, Date.today.end_of_week.to_s)
|
|
||||||
@this_week_all_issues_group_count = @this_week_all_issues.group(:pm_project_id).count
|
|
||||||
data = {}
|
|
||||||
@this_week_all_issues_group_count.keys.each do |pm_project_id|
|
|
||||||
this_project_id_requirements = @this_week_all_issues.where(pm_project_id: pm_project_id, pm_issue_type: 1)
|
|
||||||
this_project_id_tasks = @this_week_all_issues.where(pm_project_id: pm_project_id, pm_issue_type: 2)
|
|
||||||
this_project_id_bugs = @this_week_all_issues.where(pm_project_id: pm_project_id, pm_issue_type: 3)
|
|
||||||
this_project_id_close_requirements = this_project_id_requirements.where(status_id: [3,5])
|
|
||||||
this_project_id_close_tasks = this_project_id_tasks.where(status_id: [3,5])
|
|
||||||
this_project_id_close_bugs = this_project_id_bugs.where(status_id: [3,5])
|
|
||||||
data[pm_project_id] = {
|
|
||||||
this_week_requirement_issues_count: this_project_id_requirements.count,
|
|
||||||
this_week_task_issues_count: this_project_id_tasks.count,
|
|
||||||
this_week_bug_issues_count: this_project_id_bugs.count,
|
|
||||||
close_requirement_issues_count: this_project_id_close_requirements.count,
|
|
||||||
close_task_issues_count: this_project_id_close_tasks.count,
|
|
||||||
close_bug_issues_count: this_project_id_close_bugs.count,
|
|
||||||
this_week_task_issues: this_project_id_tasks
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
render :json => data
|
|
||||||
end
|
|
||||||
|
|
||||||
def group_issues
|
|
||||||
@enterprise_identifier = params[:enterprise_identifier] || ''
|
|
||||||
@all_issues = Issue.where(enterprise_identifier: @enterprise_identifier, pm_issue_type: [1,2,3])
|
|
||||||
@all_issues = @all_issues.where(pm_project_id: params[:pm_project_ids].split(",")) if params[:pm_project_ids].present?
|
|
||||||
@all_issues = @all_issues.where(pm_issue_type: params[:pm_issue_type].to_i) if params[:pm_issue_type].present?
|
|
||||||
@this_week_all_issues = @all_issues.where("due_date >= ? and start_date <= ?", Date.today.beginning_of_week.to_s, Date.today.end_of_week.to_s)
|
|
||||||
@this_week_all_issues = @this_week_all_issues.order('created_on desc')
|
|
||||||
@this_week_all_issues = kaminari_paginate(@this_week_all_issues)
|
|
||||||
end
|
|
||||||
def personal_issues
|
|
||||||
@enterprise_identifier = params[:enterprise_identifier] || ''
|
|
||||||
return render_error('请输入正确的用户ID.') if params[:user_id].blank?
|
|
||||||
@all_issues = Issue.joins(:issue_participants).where(issue_participants: {participant_id: params[:user_id], participant_type: ['assigned']})
|
|
||||||
@all_issues = @all_issues.where(enterprise_identifier: @enterprise_identifier, pm_issue_type: [1,2,3])
|
|
||||||
@this_week_all_issues = @all_issues.where("due_date >= ? and start_date <= ?", Date.today.beginning_of_week.to_s, Date.today.end_of_week.to_s).distinct
|
|
||||||
@this_week_all_issues = @this_week_all_issues.order('created_on desc')
|
|
||||||
@next_week_all_issues = @all_issues.where("due_date >= ? and start_date <=?", (Date.today.beginning_of_week+1.week).to_s, (Date.today.end_of_week+1.week).to_s).distinct
|
|
||||||
@next_week_all_issues = @next_week_all_issues.order('created_on desc')
|
|
||||||
this_week_page = params[:this_week_page] || 1
|
|
||||||
this_week_limit = params[:this_week_limit] || 15
|
|
||||||
@this_week_all_issues = @this_week_all_issues.page(this_week_page).per(this_week_limit)
|
|
||||||
next_week_page = params[:next_week_page] || 1
|
|
||||||
next_week_limit = params[:next_week_limit] || 15
|
|
||||||
@next_week_all_issues = @next_week_all_issues.page(next_week_page).per(next_week_limit)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
|
@ -55,11 +55,6 @@ class Api::V1::BaseController < ApplicationController
|
||||||
return render_forbidden if !current_user.admin? && !@project.operator?(current_user) && !(@project.fork_project.present? && @project.fork_project.operator?(current_user))
|
return render_forbidden if !current_user.admin? && !@project.operator?(current_user) && !(@project.fork_project.present? && @project.fork_project.operator?(current_user))
|
||||||
end
|
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
|
def require_public_and_member_above
|
||||||
@project = load_project
|
@project = load_project
|
||||||
|
|
|
@ -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,5 +1,5 @@
|
||||||
class Api::V1::Issues::IssueTagsController < Api::V1::BaseController
|
class Api::V1::Issues::IssueTagsController < Api::V1::BaseController
|
||||||
before_action :require_login, except: [:index, :pm_index]
|
before_action :require_login, except: [:index]
|
||||||
before_action :require_public_and_member_above, only: [:index]
|
before_action :require_public_and_member_above, only: [:index]
|
||||||
before_action :require_operate_above, only: [:create, :update, :destroy]
|
before_action :require_operate_above, only: [:create, :update, :destroy]
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ class Api::V1::Issues::JournalsController < Api::V1::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def load_issue
|
def load_issue
|
||||||
@issue = @project.issues.issue_issue.where(project_issues_index: params[:index]).where.not(id: params[:index]).take || @project.issues.issue_issue.find_by_id(params[:index])
|
@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?
|
if @issue.blank?
|
||||||
render_not_found("疑修不存在!")
|
render_not_found("疑修不存在!")
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
class Api::V1::IssuesController < Api::V1::BaseController
|
class Api::V1::IssuesController < Api::V1::BaseController
|
||||||
before_action :require_login, except: [:index, :show, :show_by_id]
|
before_action :require_login, except: [:index, :show]
|
||||||
before_action :require_public_and_member_above, only: [:index, :show, :show_by_id, :create, :update, :destroy]
|
before_action :require_public_and_member_above, only: [:index, :show, :create, :update, :destroy]
|
||||||
before_action :require_operate_above, only: [:batch_update, :batch_destroy]
|
before_action :require_operate_above, only: [:batch_update, :batch_destroy]
|
||||||
|
|
||||||
def index
|
def index
|
||||||
|
@ -22,15 +22,8 @@ class Api::V1::IssuesController < Api::V1::BaseController
|
||||||
|
|
||||||
before_action :load_issue, only: [:show, :update, :destroy]
|
before_action :load_issue, only: [:show, :update, :destroy]
|
||||||
before_action :check_issue_operate_permission, only: [: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
|
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)
|
@user_permission = current_user.present? && current_user.logged? && (@project.member?(current_user) || current_user.admin? || @issue.user == current_user)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -70,14 +63,7 @@ class Api::V1::IssuesController < Api::V1::BaseController
|
||||||
private
|
private
|
||||||
|
|
||||||
def load_issue
|
def load_issue
|
||||||
@issue = @project.issues.issue_issue.where(project_issues_index: params[:index]).where.not(id: params[:index]).take || @project.issues.issue_issue.find_by_id(params[:index])
|
@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?
|
if @issue.blank?
|
||||||
render_not_found("疑修不存在!")
|
render_not_found("疑修不存在!")
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
class Api::V1::PmIssuesController < ApplicationController
|
|
||||||
before_action :require_login, except: [:index, :show]
|
|
||||||
|
|
||||||
def index
|
|
||||||
project = Project.find_by_id(params[:project_id]) || Project.new( id: 0, user_id: 0, name:"pm_mm", identifier:"pm_mm" )
|
|
||||||
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
|
|
||||||
project = Project.find_by_id(params[:project_id]) || Project.new( id: 0, user_id: 0, name:"pm_mm", identifier:"pm_mm" )
|
|
||||||
@object_result = Api::V1::Issues::CreateService.call(project, issue_params, current_user)
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
def issue_params
|
|
||||||
params.permit(
|
|
||||||
:status_id, :priority_id, :milestone_id,
|
|
||||||
:branch_name, :start_date, :due_date,
|
|
||||||
:subject, :description, :blockchain_token_num,
|
|
||||||
:pm_project_id, :pm_sprint_id,
|
|
||||||
:issue_tag_ids => [],
|
|
||||||
:assigner_ids => [],
|
|
||||||
:attachment_ids => [],
|
|
||||||
:receivers_login => []
|
|
||||||
)
|
|
||||||
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,93 +0,0 @@
|
||||||
class Api::V1::Projects::Actions::ActionsController < Api::V1::Projects::Actions::BaseController
|
|
||||||
|
|
||||||
def new_index
|
|
||||||
@files = $gitea_client.get_repos_contents_by_owner_repo_filepath(@project&.owner&.login, @project&.identifier, ".gitea/workflows") rescue []
|
|
||||||
@workflows = params[:workflows].split(",") if params[:workflows].present?
|
|
||||||
@action_runs = Gitea::ActionRun.where(repo_id: @project.gpid)
|
|
||||||
disabled_config = Gitea::RepoUnit.where(repo_id: @project.gpid, type: 10)&.first&.config
|
|
||||||
disabled_workflows = disabled_config.present? ? JSON.parse(disabled_config)["DisabledWorkflows"] : []
|
|
||||||
@action_runs = @action_runs.where(id: params[:ids].split(",")) if params[:ids].present?
|
|
||||||
@action_runs = @action_runs.where(workflow_id: @workflows) if params[:workflows].present?
|
|
||||||
group_data = @action_runs.where(status: [1,2]).group(:workflow_id, :status).count
|
|
||||||
@result = []
|
|
||||||
@files.map{|i|i['name']}.each do |file|
|
|
||||||
if @workflows.present?
|
|
||||||
next if !@workflows.include?(file)
|
|
||||||
end
|
|
||||||
last_action_run = @action_runs.where(workflow_id: file).order(updated: :desc).first
|
|
||||||
last_action_run_json = last_action_run.present? ? {
|
|
||||||
pipeline_id: Action::Pipeline.find_by(pipeline_name: file, project_id: @project.id),
|
|
||||||
id: last_action_run.id,
|
|
||||||
schedule: last_action_run.schedule_id > 0,
|
|
||||||
title: last_action_run.title,
|
|
||||||
index: last_action_run.index,
|
|
||||||
status: last_action_run.status,
|
|
||||||
started: last_action_run.started,
|
|
||||||
stopped: last_action_run.stopped,
|
|
||||||
length: last_action_run.stopped-last_action_run.started,
|
|
||||||
created: last_action_run.created,
|
|
||||||
updated: last_action_run.updated,
|
|
||||||
} : {}
|
|
||||||
|
|
||||||
total = 0
|
|
||||||
success = 0
|
|
||||||
failure = 0
|
|
||||||
group_data.each do |k,v|
|
|
||||||
total += v if k[0] == file
|
|
||||||
success += v if k[0] == file && k[1] == 1
|
|
||||||
failure += v if k[0] == file && k[1] == 2
|
|
||||||
end
|
|
||||||
|
|
||||||
pipeline_type = 1
|
|
||||||
begin
|
|
||||||
content = Gitea::Repository::Entries::GetService.call(@project&.owner, @project&.identifier, URI.escape(file), ref: last_action_run.present? ? last_action_run.ref.gsub("refs/heads/","") : @project.default_branch)['content']
|
|
||||||
yaml_string = Base64.decode64(content).force_encoding("GBK").encode("UTF-8") unless Base64.decode64(content).force_encoding('UTF-8').valid_encoding?
|
|
||||||
yaml_string = Base64.decode64(content).force_encoding('UTF-8')
|
|
||||||
yml = YAML.safe_load(yaml_string)
|
|
||||||
pipeline_type = yml.name == file.to_s.gsub(".yml","").gsub(".yaml","") ? 2 : 1
|
|
||||||
rescue
|
|
||||||
Rails.logger.info("#{file}不能识别流水线类型")
|
|
||||||
end
|
|
||||||
@result << {
|
|
||||||
filename: file,
|
|
||||||
disabled: disabled_workflows.include?(file.to_s),
|
|
||||||
name: file.to_s.gsub(".yml","").gsub(".yaml","") ,
|
|
||||||
branch: last_action_run.present? ? last_action_run.ref.gsub("refs/heads/","") : @project.default_branch,
|
|
||||||
pipeline_type: pipeline_type,
|
|
||||||
total: total,
|
|
||||||
success: success,
|
|
||||||
failure: failure
|
|
||||||
}.merge(last_action_run_json)
|
|
||||||
end
|
|
||||||
render :json => {data: @result}
|
|
||||||
end
|
|
||||||
|
|
||||||
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,61 +0,0 @@
|
||||||
class Api::V1::Projects::Actions::RunsController < Api::V1::Projects::Actions::BaseController
|
|
||||||
|
|
||||||
def index
|
|
||||||
@files = $gitea_client.get_repos_contents_by_owner_repo_filepath(@project&.owner&.login, @project&.identifier, ".gitea/workflows") rescue []
|
|
||||||
@has_file = @files.select { |i| i['name'] == params[:workflow] }.present?
|
|
||||||
if @has_file
|
|
||||||
@result_object = Api::V1::Projects::Actions::Runs::ListService.call(@project, {workflow: params[:workflow], page: page, limit: limit}, current_user&.gitea_token)
|
|
||||||
@begin_num = (page.to_i - 1) * limit.to_i
|
|
||||||
end
|
|
||||||
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,48 +1,23 @@
|
||||||
class Api::V1::Projects::BranchesController < Api::V1::BaseController
|
class Api::V1::Projects::BranchesController < Api::V1::BaseController
|
||||||
before_action :require_public_and_member_above, only: [:index, :all]
|
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
|
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)
|
@result_object = Api::V1::Projects::Branches::ListService.call(@project, {name: params[:keyword], page: page, limit: limit}, current_user&.gitea_token)
|
||||||
end
|
end
|
||||||
|
|
||||||
def all
|
def all
|
||||||
@result_object = Api::V1::Projects::Branches::AllListService.call(@project, current_user&.gitea_token)
|
@result_object = Api::V1::Projects::Branches::AllListService.call(@project, current_user&.gitea_token)
|
||||||
end
|
end
|
||||||
|
|
||||||
before_action :require_operate_above, only: [:create, :destroy, :restore]
|
before_action :require_operate_above, only: [:create, :destroy]
|
||||||
|
|
||||||
def create
|
def create
|
||||||
@result_object = Api::V1::Projects::Branches::CreateService.call(@project, branch_params, current_user&.gitea_token)
|
@result_object = Api::V1::Projects::Branches::CreateService.call(@project, branch_params, current_user&.gitea_token)
|
||||||
@project.update_column(:updated_on, Time.now)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
@result_object = Api::V1::Projects::Branches::DeleteService.call(@project, params[:name], current_user&.gitea_token)
|
@result_object = Api::V1::Projects::Branches::DeleteService.call(@project, params[:name], current_user&.gitea_token)
|
||||||
if @result_object
|
if @result_object
|
||||||
@project.update_column(:updated_on, Time.now)
|
|
||||||
# 有开启的pr需要一同关闭
|
# 有开启的pr需要一同关闭
|
||||||
# 1、删除本仓库中存在未关闭的pr,即本仓库分支1->分支2
|
# 1、删除本仓库中存在未关闭的pr,即本仓库分支1->分支2
|
||||||
# 2、如果是fork仓库,考虑删除主仓库中存在未关闭的pr,即本仓库:分支1->主:分支2,同时分两种删除:1删除本仓库分支1,2删除主仓库分支2
|
# 2、如果是fork仓库,考虑删除主仓库中存在未关闭的pr,即本仓库:分支1->主:分支2,同时分两种删除:1删除本仓库分支1,2删除主仓库分支2
|
||||||
|
@ -58,22 +33,11 @@ class Api::V1::Projects::BranchesController < Api::V1::BaseController
|
||||||
end
|
end
|
||||||
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
|
|
||||||
@project.update_column(:updated_on, Time.now)
|
|
||||||
return render_ok
|
|
||||||
else
|
|
||||||
return render_error('恢复分支失败!')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
before_action :require_manager_above, only: [:update_default_branch]
|
before_action :require_manager_above, only: [:update_default_branch]
|
||||||
|
|
||||||
def update_default_branch
|
def update_default_branch
|
||||||
@result_object = Api::V1::Projects::Branches::UpdateDefaultBranchService.call(@project, params[:name], current_user&.gitea_token)
|
@result_object = Api::V1::Projects::Branches::UpdateDefaultBranchService.call(@project, params[:name], current_user&.gitea_token)
|
||||||
if @result_object
|
if @result_object
|
||||||
@project.update_column(:updated_on, Time.now)
|
|
||||||
return render_ok
|
return render_ok
|
||||||
else
|
else
|
||||||
return render_error('更新默认分支失败!')
|
return render_error('更新默认分支失败!')
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
class Api::V1::Projects::CommitsController < Api::V1::BaseController
|
class Api::V1::Projects::CommitsController < Api::V1::BaseController
|
||||||
before_action :require_public_and_member_above, only: [:index, :diff, :recent, :files]
|
before_action :require_public_and_member_above, only: [:index, :diff]
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@result_object = Api::V1::Projects::Commits::ListService.call(@project, {page: page, limit: limit, sha: params[:sha]}, current_user&.gitea_token)
|
@result_object = Api::V1::Projects::Commits::ListService.call(@project, {page: page, limit: limit, sha: params[:sha]}, current_user&.gitea_token)
|
||||||
|
@ -9,19 +9,4 @@ class Api::V1::Projects::CommitsController < Api::V1::BaseController
|
||||||
def diff
|
def diff
|
||||||
@result_object = Api::V1::Projects::Commits::DiffService.call(@project, params[:sha], current_user&.gitea_token)
|
@result_object = Api::V1::Projects::Commits::DiffService.call(@project, params[:sha], current_user&.gitea_token)
|
||||||
end
|
end
|
||||||
|
|
||||||
def files
|
|
||||||
if params[:filepath].present?
|
|
||||||
@result_object = $gitea_hat_client.get_repos_commits_files_by_owner_repo_sha_filepath(@project&.owner.login, @project&.identifier, params[:sha], CGI.escape(params[:filepath]), {query: {token: current_user&.gitea_token}})
|
|
||||||
else
|
|
||||||
@result_object = $gitea_hat_client.get_repos_commits_files_by_owner_repo_sha(@project&.owner.login, @project&.identifier, params[:sha], {query: {token: current_user&.gitea_token, page: page, limit: limit}})
|
|
||||||
end
|
|
||||||
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
|
end
|
|
@ -1,58 +0,0 @@
|
||||||
class Api::V1::Projects::CompareController < Api::V1::BaseController
|
|
||||||
|
|
||||||
before_action :require_public_and_member_above, only: [:files]
|
|
||||||
|
|
||||||
def files
|
|
||||||
load_compare_params
|
|
||||||
if params[:type] == "sha"
|
|
||||||
@compare_result ||= gitea_compare_files(@base, @head)
|
|
||||||
else
|
|
||||||
@compare_result ||= @head.include?(":") ? gitea_compare_files(@base, @head) : gitea_compare_files(@head, @base)
|
|
||||||
@merge_status, @merge_message = get_merge_message
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
def load_compare_params
|
|
||||||
@base = params[:base].include?(":") ? Addressable::URI.unescape(params[:base].split(":")[0]) + ':' + Base64.decode64(params[:base].split(":")[1]) : Base64.decode64(params[:base])
|
|
||||||
@head = params[:head].include?(":") ? Addressable::URI.unescape(params[:head].split(":")[0]) + ':' + Base64.decode64(params[:head].split(":")[1]) : Base64.decode64(params[:head])
|
|
||||||
end
|
|
||||||
|
|
||||||
def gitea_compare_files(base, head)
|
|
||||||
if params[:filepath].present?
|
|
||||||
$gitea_hat_client.get_repos_compare_by_owner_repo_baseref_headref(@project&.owner&.login, @project.identifier, Addressable::URI.escape(base), Addressable::URI.escape(head), {query: {token: current_user&.gitea_token, isFiles: true, filepath: params[:filepath]}})
|
|
||||||
else
|
|
||||||
$gitea_hat_client.get_repos_compare_by_owner_repo_baseref_headref(@project&.owner&.login, @project.identifier, Addressable::URI.escape(base), Addressable::URI.escape(head), {query: {page:page,limit:limit,token: current_user&.gitea_token, isFiles: true}})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def get_merge_message
|
|
||||||
if @base.blank? || @head.blank?
|
|
||||||
return -2, "请选择分支"
|
|
||||||
else
|
|
||||||
return -2, "目标仓库未开启合并请求(PR)功能" unless @project.has_menu_permission("pulls")
|
|
||||||
if @head.include?(":")
|
|
||||||
fork_project = @project.forked_projects.joins(:owner).where(users: {login: @head.to_s.split("/")[0]}).take
|
|
||||||
return -2, "请选择正确的仓库" unless fork_project.present?
|
|
||||||
@exist_pullrequest = @project.pull_requests.where(is_original: true, head: @head.to_s.split(":")[1], base: @base, status: 0, fork_project_id: fork_project.id).take
|
|
||||||
else
|
|
||||||
@exist_pullrequest = @project.pull_requests.where(is_original: false, head: @base, base: @head, status: 0).take
|
|
||||||
end
|
|
||||||
if @exist_pullrequest.present?
|
|
||||||
return -2, "在这些分支之间的合并请求已存在:<a href='/#{@owner.login}/#{@project.identifier}/pulls/#{@exist_pullrequest.id}'>#{@exist_pullrequest.try(:title)}</a>"
|
|
||||||
else
|
|
||||||
Rails.logger.info @compare_result
|
|
||||||
if params[:filepath].present?
|
|
||||||
if @compare_result["Commits"].blank? && @compare_result["Diff"].blank?
|
|
||||||
return -2, "分支内容相同,无需创建合并请求"
|
|
||||||
end
|
|
||||||
else
|
|
||||||
if @compare_result[:total_data].to_i < 1
|
|
||||||
return -2, "分支内容相同,无需创建合并请求"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return 0, "可以合并"
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,51 +0,0 @@
|
||||||
class Api::V1::Projects::DatasetsController < Api::V1::BaseController
|
|
||||||
before_action :require_public_and_member_above, only: [:show]
|
|
||||||
before_action :require_member_above, only: [:create, :update]
|
|
||||||
before_action :find_dataset, only: [:update, :show]
|
|
||||||
before_action :check_menu_authorize
|
|
||||||
|
|
||||||
def create
|
|
||||||
::Projects::Datasets::CreateForm.new(dataset_params).validate!
|
|
||||||
return render_error('该项目下已存在数据集!') if @project.project_dataset.present?
|
|
||||||
@project_dataset = ProjectDataset.new(dataset_params.merge!(project_id: @project.id))
|
|
||||||
if @project_dataset.save!
|
|
||||||
render_ok
|
|
||||||
else
|
|
||||||
render_error('创建数据集失败!')
|
|
||||||
end
|
|
||||||
rescue Exception => e
|
|
||||||
uid_logger_error(e.message)
|
|
||||||
tip_exception(e.message)
|
|
||||||
end
|
|
||||||
|
|
||||||
def update
|
|
||||||
::Projects::Datasets::CreateForm.new(dataset_params).validate!
|
|
||||||
@project_dataset.attributes = dataset_params
|
|
||||||
if @project_dataset.save!
|
|
||||||
render_ok
|
|
||||||
else
|
|
||||||
render_error("更新数据集失败!")
|
|
||||||
end
|
|
||||||
rescue Exception => e
|
|
||||||
uid_logger_error(e.message)
|
|
||||||
tip_exception(e.message)
|
|
||||||
end
|
|
||||||
|
|
||||||
def show
|
|
||||||
@attachments = kaminari_paginate(@project_dataset.attachments.includes(:author))
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
def dataset_params
|
|
||||||
params.permit(:title, :description, :license_id, :paper_content)
|
|
||||||
end
|
|
||||||
|
|
||||||
def find_dataset
|
|
||||||
@project_dataset = @project.project_dataset
|
|
||||||
return render_not_found unless @project_dataset.present?
|
|
||||||
end
|
|
||||||
|
|
||||||
def check_menu_authorize
|
|
||||||
return render_not_found unless @project.has_menu_permission("dataset")
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,31 +0,0 @@
|
||||||
class Api::V1::Projects::OssHealthMeasuringController < Api::V1::BaseController
|
|
||||||
|
|
||||||
def index
|
|
||||||
|
|
||||||
url = URI("#{EduSetting.get("ohm_server_url")}/api/OSS_Health_Measuring/#{params[:owner]}/#{params[:repo]}")
|
|
||||||
|
|
||||||
http = Net::HTTP.new(url.host, url.port);
|
|
||||||
request = Net::HTTP::Get.new(url)
|
|
||||||
response = http.request(request)
|
|
||||||
render :json=> response.read_body
|
|
||||||
end
|
|
||||||
|
|
||||||
def keyid
|
|
||||||
url = URI("#{EduSetting.get("ohm_server_url")}/api/OSS_Health_Measuring/#{params[:owner]}/#{params[:repo]}/#{params[:key_id]}")
|
|
||||||
|
|
||||||
http = Net::HTTP.new(url.host, url.port);
|
|
||||||
request = Net::HTTP::Get.new(url)
|
|
||||||
response = http.request(request)
|
|
||||||
render :json=> response.read_body
|
|
||||||
end
|
|
||||||
|
|
||||||
def can_get
|
|
||||||
url = URI("#{EduSetting.get("ohm_server_url")}/api/OHM_can_get/#{params[:owner]}/#{params[:repo]}")
|
|
||||||
|
|
||||||
http = Net::HTTP.new(url.host, url.port);
|
|
||||||
request = Net::HTTP::Get.new(url)
|
|
||||||
response = http.request(request)
|
|
||||||
render :json=> response.read_body
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,204 +0,0 @@
|
||||||
class Api::V1::Projects::PortraitController < Api::V1::BaseController
|
|
||||||
before_action :require_public_and_member_above
|
|
||||||
|
|
||||||
def index
|
|
||||||
Cache::V2::PlatformStatisticService.new().reset
|
|
||||||
@platform_statistic = $redis_cache.hgetall("v2-platform-statistic")
|
|
||||||
|
|
||||||
# 社区影响力
|
|
||||||
praise_count = PraiseTread.where(praise_tread_object_type: "Project", praise_tread_object_id: @project.id).count
|
|
||||||
praise_count = PraiseTread.where(praise_tread_object_type: "Project", praise_tread_object_id: @project.id).count
|
|
||||||
watcher_count = Watcher.where(watchable_type:"Project", watchable_id: @project.id).count
|
|
||||||
fork_count = ForkUser.where(project_id: @project.id).count
|
|
||||||
community_impact_praise = @platform_statistic['max-praise-count'].to_i == 0 ? 0 : 30*(praise_count.to_f/@platform_statistic['max-praise-count'].to_i)
|
|
||||||
community_impact_watcher = @platform_statistic['max-watcher-count'].to_i == 0 ? 0 : 30*(watcher_count.to_f/@platform_statistic['max-watcher-count'].to_i)
|
|
||||||
community_impact_fork = @platform_statistic['max-fork-count'].to_i == 0 ? 0 : 40*(fork_count.to_f/@platform_statistic['max-fork-count'].to_i)
|
|
||||||
community_impact = format("%.2f", community_impact_praise + community_impact_watcher + community_impact_fork)
|
|
||||||
|
|
||||||
# 项目成熟度
|
|
||||||
pullrequest_count = PullRequest.where(project_id: @project.id).count
|
|
||||||
complete_issue_count = Issue.issue_issue.where(project_id: @project.id, status_id: [3,5]).count
|
|
||||||
project_create_day = (Time.now.to_i - @project.created_on.to_i)/(3600*24)
|
|
||||||
max_project_create_day = (Time.now.to_i - Project.order("created_on desc").last.created_on.to_i)/(3600*24)
|
|
||||||
project_maturity_pullrequest = @platform_statistic['max-pullrequest-count'].to_i == 0? 0 : 40*(pullrequest_count.to_f/@platform_statistic['max-pullrequest-count'].to_i)
|
|
||||||
project_maturity_complete_issue = @platform_statistic['max-complete-issue-count'].to_i == 0? 0 : 40*(complete_issue_count.to_f/@platform_statistic['max-complete-issue-count'].to_i)
|
|
||||||
project_maturity_project_create_day = max_project_create_day.to_i <= 0 || project_create_day.to_i <= 0 ? 0 : 20*(Math.sqrt(project_create_day).to_f/Math.sqrt(max_project_create_day))
|
|
||||||
project_maturity = format("%.2f", project_maturity_pullrequest + project_maturity_complete_issue + project_maturity_project_create_day)
|
|
||||||
|
|
||||||
# 项目健康度
|
|
||||||
member_count = Member.where(project_id: @project.id).count
|
|
||||||
max_member_count = @platform_statistic['max-member-count'].to_i
|
|
||||||
|
|
||||||
project_last_commit = CommitLog.joins(:project).merge(Project.common).where(project_id: @project.id).order("created_at desc").first
|
|
||||||
last_commit_day = project_last_commit.present? ? (Time.now.to_i - project_last_commit.created_at.to_i)/(3600*24) : 0
|
|
||||||
|
|
||||||
has_license = @project.license.present? ? 1 : 0
|
|
||||||
|
|
||||||
closed_pullrequest_count = PullRequest.where(project_id: @project.id).merged_and_closed.count
|
|
||||||
closed_issue_count = Issue.issue_issue.where(project_id: @project.id).closed.count
|
|
||||||
pullrequest_count = PullRequest.where(project_id: @project.id).count
|
|
||||||
issue_count = Issue.issue_issue.where(project_id: @project.id).count
|
|
||||||
health_code1 = max_member_count.to_i == 0 ? 0 : 0.3*(member_count.to_f/max_member_count)
|
|
||||||
health_code2 = last_commit_day.to_i == 0 ? 0 : 0.7*(1.to_f/(1+last_commit_day))
|
|
||||||
health_code = 10 * (health_code1 + health_code2)
|
|
||||||
health_license = 10 * has_license
|
|
||||||
health_pullrequest = pullrequest_count <= 1 ? 0 : 40 * (closed_pullrequest_count.to_f/pullrequest_count)*(1-1/Math.sqrt(pullrequest_count+1))
|
|
||||||
health_issue = issue_count <= 1 ? 0 : 40 * (closed_issue_count.to_f/issue_count)*(1-1/Math.sqrt(issue_count+1))
|
|
||||||
|
|
||||||
project_health = format("%.2f", health_code + health_license + health_pullrequest + health_issue)
|
|
||||||
|
|
||||||
# 团队影响度
|
|
||||||
member_count = Member.where(project_id: @project.id).count
|
|
||||||
max_member_count = @platform_statistic['max-member-count'].to_i
|
|
||||||
recent_one_month_member_count = Member.where(project_id:@project.id).where("created_on >?", Time.now - 30.days).count
|
|
||||||
max_recent_one_month_member_count = @platform_statistic['max-recent-one-month-member-count'].to_i
|
|
||||||
issue_assigner_count = IssueAssigner.joins(:issue).merge(Issue.issue_issue).where(issues: {project_id: @project.id}).distinct.count
|
|
||||||
team_impact_member = 40*(member_count.to_f/max_member_count)
|
|
||||||
team_impact_recent_member = 40*(recent_one_month_member_count.to_f/max_recent_one_month_member_count)
|
|
||||||
team_impact_issue_assigner = 20*(issue_assigner_count.to_f/max_member_count)
|
|
||||||
team_impact = format("%.2f", team_impact_member + team_impact_recent_member + team_impact_issue_assigner)
|
|
||||||
|
|
||||||
# 开发活跃度
|
|
||||||
recent_one_month_commit_count = CommitLog.joins(:project).merge(Project.common).where(project_id: @project.id).where("created_at >?", Time.now - 30.days).count
|
|
||||||
recent_one_month_pullrequest_count = PullRequest.where(project_id: @project.id).where("created_at >?", Time.now - 30.days).count
|
|
||||||
recent_one_month_issue_count = Issue.issue_issue.where(project_id: @project.id).where("created_on >?", Time.now - 30.days).count
|
|
||||||
recent_one_month_release_count = VersionRelease.joins(:repository).where(repositories: {project_id: @project.id}).where("created_at >?", Time.now - 30.days).count
|
|
||||||
max_recent_one_month_commit_count = @platform_statistic['max-recent-one-month-commit-count'].to_i
|
|
||||||
max_recent_one_month_pullrequest_count = @platform_statistic['max-recent-one-month-pullrequest-count'].to_i
|
|
||||||
max_recent_one_month_issue_count = @platform_statistic['max-recent-one-month-issue-count'].to_i
|
|
||||||
max_recent_one_month_release_count = @platform_statistic['max-recent-one-month-release-count'].to_i
|
|
||||||
develop_activity_commit = max_recent_one_month_commit_count.zero? ? 0 : 40*(recent_one_month_commit_count.to_f/max_recent_one_month_commit_count)
|
|
||||||
develop_activity_issue = max_recent_one_month_issue_count.zero? ? 0 : 20*(recent_one_month_issue_count.to_f/max_recent_one_month_issue_count)
|
|
||||||
develop_activity_pullrequest = max_recent_one_month_pullrequest_count.zero? ? 0 : 20*(recent_one_month_pullrequest_count.to_f/max_recent_one_month_pullrequest_count)
|
|
||||||
develop_activity_release = max_recent_one_month_release_count.zero? ? 0 : 20*(recent_one_month_release_count.to_f/max_recent_one_month_release_count)
|
|
||||||
develop_activity = format("%.2f", develop_activity_commit + develop_activity_issue + develop_activity_pullrequest + develop_activity_release)
|
|
||||||
|
|
||||||
render :json => {community_impact: community_impact, project_maturity: project_maturity, project_health: project_health, team_impact: team_impact, develop_activity: develop_activity}
|
|
||||||
end
|
|
||||||
|
|
||||||
# 社区影响力
|
|
||||||
def community_impact
|
|
||||||
Cache::V2::PlatformStatisticService.new().reset
|
|
||||||
@platform_statistic = $redis_cache.hgetall("v2-platform-statistic")
|
|
||||||
praise_count = PraiseTread.where(praise_tread_object_type: "Project", praise_tread_object_id: @project.id).count
|
|
||||||
watcher_count = Watcher.where(watchable_type:"Project", watchable_id: @project.id).count
|
|
||||||
fork_count = ForkUser.where(project_id: @project.id).count
|
|
||||||
community_impact_praise = @platform_statistic['max-praise-count'].to_i == 0 ? 0 : 30*(praise_count.to_f/@platform_statistic['max-praise-count'].to_i)
|
|
||||||
community_impact_watcher = @platform_statistic['max-watcher-count'].to_i == 0 ? 0 : 30*(watcher_count.to_f/@platform_statistic['max-watcher-count'].to_i)
|
|
||||||
community_impact_fork = @platform_statistic['max-fork-count'].to_i == 0 ? 0 : 40*(fork_count.to_f/@platform_statistic['max-fork-count'].to_i)
|
|
||||||
community_impact = format("%.2f", community_impact_praise + community_impact_watcher + community_impact_fork)
|
|
||||||
|
|
||||||
render :json => {
|
|
||||||
community_impact_praise: community_impact_praise,
|
|
||||||
community_impact_watcher: community_impact_watcher,
|
|
||||||
community_impact_fork: community_impact_fork,
|
|
||||||
community_impact: community_impact
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
# 项目成熟度
|
|
||||||
def project_maturity
|
|
||||||
Cache::V2::PlatformStatisticService.new().reset
|
|
||||||
@platform_statistic = $redis_cache.hgetall("v2-platform-statistic")
|
|
||||||
pullrequest_count = PullRequest.where(project_id: @project.id).count
|
|
||||||
complete_issue_count = Issue.issue_issue.where(project_id: @project.id, status_id: [3,5]).count
|
|
||||||
project_create_day = (Time.now.to_i - @project.created_on.to_i)/(3600*24)
|
|
||||||
max_project_create_day = (Time.now.to_i - Project.order("created_on desc").last.created_on.to_i)/(3600*24)
|
|
||||||
project_maturity_pullrequest = @platform_statistic['max-pullrequest-count'].to_i == 0? 0 : 40*(pullrequest_count.to_f/@platform_statistic['max-pullrequest-count'].to_i)
|
|
||||||
project_maturity_complete_issue = @platform_statistic['max-complete-issue-count'].to_i == 0? 0 : 40*(complete_issue_count.to_f/@platform_statistic['max-complete-issue-count'].to_i)
|
|
||||||
project_maturity_project_create_day = max_project_create_day.to_i <= 0 || project_create_day.to_i <= 0 ? 0 : 20*(Math.sqrt(project_create_day).to_f/Math.sqrt(max_project_create_day))
|
|
||||||
project_maturity = format("%.2f", project_maturity_pullrequest + project_maturity_complete_issue + project_maturity_project_create_day)
|
|
||||||
|
|
||||||
render :json => {
|
|
||||||
project_maturity_pullrequest: project_maturity_pullrequest,
|
|
||||||
project_maturity_complete_issue: project_maturity_complete_issue,
|
|
||||||
project_maturity_project_create_day: project_maturity_project_create_day,
|
|
||||||
project_maturity: project_maturity
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
# 项目健康度
|
|
||||||
def project_health
|
|
||||||
Cache::V2::PlatformStatisticService.new().reset
|
|
||||||
@platform_statistic = $redis_cache.hgetall("v2-platform-statistic")
|
|
||||||
|
|
||||||
member_count = Member.where(project_id: @project.id).count
|
|
||||||
max_member_count = @platform_statistic['max-member-count'].to_i
|
|
||||||
|
|
||||||
project_last_commit = CommitLog.joins(:project).merge(Project.common).where(project_id: @project.id).order("created_at desc").first
|
|
||||||
last_commit_day = project_last_commit.present? ? (Time.now.to_i - project_last_commit.created_at.to_i)/(3600*24) : 0
|
|
||||||
|
|
||||||
has_license = @project.license.present? ? 1 : 0
|
|
||||||
|
|
||||||
closed_pullrequest_count = PullRequest.where(project_id: @project.id, status: 1).count
|
|
||||||
closed_issue_count = Issue.issue_issue.where(project_id: @project.id, status_id: [3,5]).count
|
|
||||||
pullrequest_count = PullRequest.where(project_id: @project.id).count
|
|
||||||
issue_count = Issue.issue_issue.where(project_id: @project.id).count
|
|
||||||
health_code1 = max_member_count.to_i == 0 ? 0 : 0.3*(member_count.to_f/max_member_count)
|
|
||||||
health_code2 = last_commit_day.to_i == 0 ? 0 : 0.7*(1.to_f/(1+last_commit_day*0.1))
|
|
||||||
health_code = 10 * (health_code1 + health_code2)
|
|
||||||
health_license = 10 * has_license
|
|
||||||
health_pullrequest = pullrequest_count <= 1 ? 0 : 40 * (closed_pullrequest_count.to_f/pullrequest_count)*(1-1/Math.sqrt(pullrequest_count+1))
|
|
||||||
health_issue = issue_count <= 1 ? 0 : 40 * (closed_issue_count.to_f/issue_count)*(1-1/Math.sqrt(issue_count+1))
|
|
||||||
|
|
||||||
project_health = format("%.2f", health_code + health_license + health_pullrequest + health_issue)
|
|
||||||
|
|
||||||
render :json => {
|
|
||||||
health_code: health_code,
|
|
||||||
health_license: health_license,
|
|
||||||
health_pullrequest: health_pullrequest,
|
|
||||||
health_issue: health_issue,
|
|
||||||
project_health: project_health
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
# 团队健康度
|
|
||||||
def team_impact
|
|
||||||
Cache::V2::PlatformStatisticService.new().reset
|
|
||||||
@platform_statistic = $redis_cache.hgetall("v2-platform-statistic")
|
|
||||||
member_count = Member.where(project_id: @project.id).count
|
|
||||||
max_member_count = @platform_statistic['max-member-count'].to_i
|
|
||||||
recent_one_month_member_count = Member.where(project_id:@project.id).where("created_on >?", Time.now - 30.days).count
|
|
||||||
max_recent_one_month_member_count = @platform_statistic['max-recent-one-month-member-count'].to_i
|
|
||||||
issue_assigner_count = IssueAssigner.joins(:issue).merge(Issue.issue_issue).where(issues: {project_id: @project.id}).distinct.count
|
|
||||||
project_member_count = @project.owner.is_a?(User) ? member_count : @project.owner.organization_users.count
|
|
||||||
team_impact_member = 40*(member_count.to_f/max_member_count)
|
|
||||||
team_impact_recent_member = 40*(recent_one_month_member_count.to_f/max_recent_one_month_member_count)
|
|
||||||
team_impact_issue_assigner = 20*(issue_assigner_count.to_f/project_member_count)
|
|
||||||
team_impact = format("%.2f", team_impact_member + team_impact_recent_member + team_impact_issue_assigner)
|
|
||||||
|
|
||||||
render :json => {
|
|
||||||
team_impact_member: team_impact_member,
|
|
||||||
team_impact_recent_member: team_impact_recent_member,
|
|
||||||
team_impact_issue_assigner: team_impact_issue_assigner,
|
|
||||||
team_impact: team_impact
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
# 开发活跃度
|
|
||||||
def develop_activity
|
|
||||||
Cache::V2::PlatformStatisticService.new().reset
|
|
||||||
@platform_statistic = $redis_cache.hgetall("v2-platform-statistic")
|
|
||||||
recent_one_month_commit_count = CommitLog.joins(:project).merge(Project.common).where(project_id: @project.id).where("created_at >?", Time.now - 30.days).count
|
|
||||||
recent_one_month_pullrequest_count = PullRequest.where(project_id: @project.id).where("created_at >?", Time.now - 30.days).count
|
|
||||||
recent_one_month_issue_count = Issue.issue_issue.where(project_id: @project.id).where("created_on >?", Time.now - 30.days).count
|
|
||||||
recent_one_month_release_count = VersionRelease.joins(:repository).where(repositories: {project_id: @project.id}).where("created_at >?", Time.now - 30.days).count
|
|
||||||
max_recent_one_month_commit_count = @platform_statistic['max-recent-one-month-commit-count'].to_i
|
|
||||||
max_recent_one_month_pullrequest_count = @platform_statistic['max-recent-one-month-pullrequest-count'].to_i
|
|
||||||
max_recent_one_month_issue_count = @platform_statistic['max-recent-one-month-issue-count'].to_i
|
|
||||||
max_recent_one_month_release_count = @platform_statistic['max-recent-one-month-release-count'].to_i
|
|
||||||
develop_activity_commit = max_recent_one_month_commit_count.zero? ? 0 : 40*(recent_one_month_commit_count.to_f/max_recent_one_month_commit_count)
|
|
||||||
develop_activity_issue = max_recent_one_month_issue_count.zero? ? 0 : 20*(recent_one_month_issue_count.to_f/max_recent_one_month_issue_count)
|
|
||||||
develop_activity_pullrequest = max_recent_one_month_pullrequest_count.zero? ? 0 : 20*(recent_one_month_pullrequest_count.to_f/max_recent_one_month_pullrequest_count)
|
|
||||||
develop_activity_release = max_recent_one_month_release_count.zero? ? 0 : 20*(recent_one_month_release_count.to_f/max_recent_one_month_release_count)
|
|
||||||
develop_activity = format("%.2f", develop_activity_commit + develop_activity_issue + develop_activity_pullrequest + develop_activity_release)
|
|
||||||
|
|
||||||
render :json => {
|
|
||||||
develop_activity_commit: develop_activity_commit,
|
|
||||||
develop_activity_issue: develop_activity_issue,
|
|
||||||
develop_activity_pullrequest: develop_activity_pullrequest,
|
|
||||||
develop_activity_release: develop_activity_release,
|
|
||||||
develop_activity: develop_activity
|
|
||||||
}
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -6,21 +6,13 @@ class Api::V1::Projects::Pulls::PullsController < Api::V1::BaseController
|
||||||
@pulls = kaminari_paginate(@pulls)
|
@pulls = kaminari_paginate(@pulls)
|
||||||
end
|
end
|
||||||
|
|
||||||
before_action :load_pull_request, only: [:show, :files]
|
before_action :load_pull_request, only: [:show]
|
||||||
|
|
||||||
def show
|
def show
|
||||||
@result_object = Api::V1::Projects::Pulls::GetService.call(@project, @pull_request, current_user&.gitea_token)
|
@result_object = Api::V1::Projects::Pulls::GetService.call(@project, @pull_request, current_user&.gitea_token)
|
||||||
@last_review = @pull_request.reviews.order(created_at: :desc).take
|
@last_review = @pull_request.reviews.order(created_at: :desc).take
|
||||||
end
|
end
|
||||||
|
|
||||||
def files
|
|
||||||
if params[:filepath].present?
|
|
||||||
@result_object = $gitea_hat_client.get_repos_pulls_files_by_owner_repo_index_filepath(@project&.owner.login, @project&.identifier, @pull_request.gitea_number, CGI.escape(params[:filepath]), {query: {token: current_user&.gitea_token}})
|
|
||||||
else
|
|
||||||
@result_object = $gitea_hat_client.get_repos_pulls_files_by_owner_repo_index(@project&.owner.login, @project&.identifier, @pull_request.gitea_number, {query: {isNew: "true",token: current_user&.gitea_token, page: page, limit: limit}})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
def query_params
|
def query_params
|
||||||
params.permit(:status, :keyword, :priority_id, :issue_tag_id, :version_id, :reviewer_id, :sort_by, :sort_direction)
|
params.permit(:status, :keyword, :priority_id, :issue_tag_id, :version_id, :reviewer_id, :sort_by, :sort_direction)
|
||||||
|
|
|
@ -1,148 +0,0 @@
|
||||||
class Api::V1::Projects::SyncRepositoriesController < Api::V1::BaseController
|
|
||||||
before_action :require_public_and_member_above, except: [:sync]
|
|
||||||
before_action :load_project, only: [:sync]
|
|
||||||
|
|
||||||
def index
|
|
||||||
@sync_repositories = @project.sync_repositories
|
|
||||||
@group_sync_repository = @project.sync_repositories.group(:type, :external_repo_address, :sync_granularity, :external_token).count
|
|
||||||
end
|
|
||||||
|
|
||||||
def create
|
|
||||||
@sync_repository1, @sync_repository2, @sync_repository_branch1, @sync_repository_branch2 = Api::V1::Projects::SyncRepositories::CreateService.call(@project, sync_repository_params)
|
|
||||||
rescue Exception => e
|
|
||||||
uid_logger_error(e.message)
|
|
||||||
tip_exception(e.message)
|
|
||||||
end
|
|
||||||
|
|
||||||
def update_info
|
|
||||||
return render_error("请输入正确的同步仓库ID") unless params[:sync_repository_ids].present?
|
|
||||||
Api::V1::Projects::SyncRepositories::UpdateService.call(@project, params[:sync_repository_ids], sync_repository_update_params)
|
|
||||||
render_ok
|
|
||||||
rescue Exception => e
|
|
||||||
uid_logger_error(e.message)
|
|
||||||
tip_exception(e.message)
|
|
||||||
end
|
|
||||||
|
|
||||||
def sync
|
|
||||||
return render_error("请输入正确的同步方向!") if params[:sync_direction].blank?
|
|
||||||
if params[:repo_type].present?
|
|
||||||
@sync_repositories = SyncRepository.where(project: @project, type: params[:repo_type], sync_direction: params[:sync_direction])
|
|
||||||
else
|
|
||||||
@sync_repositories = SyncRepository.where(project: @project, sync_direction: params[:sync_direction])
|
|
||||||
end
|
|
||||||
branch = params[:payload].present? ? JSON.parse(params[:payload])["ref"].split("/")[-1] : params[:ref].split("/")[-1] rescue nil
|
|
||||||
if params[:sync_direction].to_i == 1
|
|
||||||
@sync_repository_branches = SyncRepositoryBranch.where(sync_repository_id: @sync_repositories, gitlink_branch_name: branch, enable: true)
|
|
||||||
else
|
|
||||||
@sync_repository_branches = SyncRepositoryBranch.where(sync_repository_id: @sync_repositories, external_branch_name: branch, enable: true)
|
|
||||||
end
|
|
||||||
# 全部分支同步暂时不做
|
|
||||||
# @sync_repositories.each do |item|
|
|
||||||
# TouchSyncJob.perform_later(item)
|
|
||||||
# end
|
|
||||||
@sync_repository_branches.each do |item|
|
|
||||||
TouchSyncJob.set(wait: 5.seconds).perform_later(item)
|
|
||||||
end
|
|
||||||
rescue Exception => e
|
|
||||||
uid_logger_error(e.message)
|
|
||||||
tip_exception(e.message)
|
|
||||||
end
|
|
||||||
|
|
||||||
def unbind
|
|
||||||
return render_error("请输入正确的同步仓库ID") unless params[:sync_repository_ids].present?
|
|
||||||
@sync_repositories = SyncRepository.where(id: params[:sync_repository_ids].split(","))
|
|
||||||
@sync_repositories.each do |repo|
|
|
||||||
# Reposync::DeleteRepoService.call(repo.repo_name) # 解绑操作放在回调里
|
|
||||||
Api::V1::Projects::Webhooks::DeleteService.call(@project, repo.webhook_gid)
|
|
||||||
repo.destroy
|
|
||||||
end
|
|
||||||
render_ok
|
|
||||||
rescue Exception => e
|
|
||||||
uid_logger_error(e.message)
|
|
||||||
tip_exception(e.message)
|
|
||||||
end
|
|
||||||
|
|
||||||
def change_enable
|
|
||||||
return render_error("请输入正确的仓库类型") if params[:repo_type].blank?
|
|
||||||
return render_error("请输入正确的分支名称") if params[:gitlink_branch_name].blank? || params[:external_branch_name].blank?
|
|
||||||
# return render_error("请输入正确的状态") if params[:enable].blank?
|
|
||||||
@sync_repository_branches = SyncRepositoryBranch.joins(:sync_repository).where(sync_repositories: {project_id: @project.id, type: params[:repo_type]}, gitlink_branch_name: params[:gitlink_branch_name], external_branch_name: params[:external_branch_name])
|
|
||||||
if @sync_repository_branches.update_all({enable: params[:enable]})
|
|
||||||
@sync_repository_branches.each do |branch|
|
|
||||||
branch_sync_direction = branch&.sync_repository&.sync_direction.to_i
|
|
||||||
if branch_sync_direction == 1
|
|
||||||
Reposync::UpdateBranchStatusService.call(branch&.sync_repository&.repo_name, branch.gitlink_branch_name, params[:enable])
|
|
||||||
else
|
|
||||||
Reposync::UpdateBranchStatusService.call(branch&.sync_repository&.repo_name, branch.external_branch_name, params[:enable])
|
|
||||||
end
|
|
||||||
TouchSyncJob.perform_later(branch) if params[:enable] && branch_sync_direction == params[:first_sync_direction].to_i
|
|
||||||
end
|
|
||||||
render_ok
|
|
||||||
else
|
|
||||||
render_error("更新失败!")
|
|
||||||
end
|
|
||||||
rescue Exception => e
|
|
||||||
uid_logger_error(e.message)
|
|
||||||
tip_exception(e.message)
|
|
||||||
end
|
|
||||||
|
|
||||||
def create_branch
|
|
||||||
return render_error("请输入正确的同步仓库ID") unless params[:sync_repository_ids].present?
|
|
||||||
return render_error("请输入正确的Gitlink分支名称") unless params[:gitlink_branch_name].present?
|
|
||||||
return render_error("请输入正确的外部仓库分支名称") unless params[:external_branch_name].present?
|
|
||||||
return render_error("请输入正确的首次同步方向") unless params[:first_sync_direction].present?
|
|
||||||
|
|
||||||
params[:sync_repository_ids].split(",").each do |id|
|
|
||||||
repo = SyncRepository.find_by_id id
|
|
||||||
branch = Reposync::CreateSyncBranchService.call(repo.repo_name, params[:gitlink_branch_name], params[:external_branch_name])
|
|
||||||
return render_error(branch[2]) if branch[0].to_i !=0
|
|
||||||
sync_branch = SyncRepositoryBranch.create!(sync_repository_id: id, gitlink_branch_name: params[:gitlink_branch_name], external_branch_name: params[:external_branch_name], reposync_branch_id: branch[1]['id'])
|
|
||||||
TouchSyncJob.perform_later(sync_branch) if params[:first_sync_direction].to_i == repo.sync_direction
|
|
||||||
end
|
|
||||||
render_ok
|
|
||||||
rescue Exception => e
|
|
||||||
uid_logger_error(e.message)
|
|
||||||
tip_exception(e.message)
|
|
||||||
end
|
|
||||||
|
|
||||||
def branches
|
|
||||||
return render_error("请输入正确的同步仓库ID") unless params[:sync_repository_ids].present?
|
|
||||||
@sync_repository_branches = SyncRepositoryBranch.where(sync_repository_id: params[:sync_repository_ids].split(","))
|
|
||||||
@sync_repository_branches = @sync_repository_branches.ransack(gitlink_branch_name_or_external_branch_name_cont: params[:branch_name]).result if params[:branch_name].present?
|
|
||||||
@group_sync_repository_branch = @sync_repository_branches.joins(:sync_repository).group("sync_repositories.type, sync_repository_branches.gitlink_branch_name, sync_repository_branches.external_branch_name").select("sync_repositories.type as type,max(sync_repository_branches.updated_at) as updated_at, sync_repository_branches.gitlink_branch_name, sync_repository_branches.external_branch_name").sort_by{|i|i.updated_at}
|
|
||||||
@each_json = []
|
|
||||||
@group_sync_repository_branch.each do |item|
|
|
||||||
branches = @sync_repository_branches.joins(:sync_repository).where(sync_repositories: {type: item.type}, gitlink_branch_name: item.gitlink_branch_name, external_branch_name: item.external_branch_name).order(sync_time: :desc)
|
|
||||||
branch = branches.first
|
|
||||||
@each_json << {
|
|
||||||
gitlink_branch_name: item.gitlink_branch_name,
|
|
||||||
external_branch_name: item.external_branch_name,
|
|
||||||
type: branch&.sync_repository&.type,
|
|
||||||
sync_time: branch.sync_time.present? ? branch.sync_time.strftime("%Y-%m-%d %H:%M:%S") : nil,
|
|
||||||
sync_status: branch.sync_status,
|
|
||||||
enable: branch.enable,
|
|
||||||
enable_num: branch.enable ? 1 : 0,
|
|
||||||
created_at: branch.created_at.to_i,
|
|
||||||
reposync_branch_ids: branches.pluck(:reposync_branch_id)
|
|
||||||
}
|
|
||||||
end
|
|
||||||
@each_json = @each_json.sort_by{|h| [-h[:enable_num], h[:created_at]]}
|
|
||||||
render :json => {total_count: @group_sync_repository_branch.count, sync_repository_branches: @each_json}
|
|
||||||
end
|
|
||||||
|
|
||||||
def history
|
|
||||||
return render_error("请输入正确的同步分支ID") unless params[:reposync_branch_ids]
|
|
||||||
@branch = SyncRepositoryBranch.find_by(reposync_branch_id: params[:reposync_branch_ids].split(",")[0])
|
|
||||||
_, @reposync_branch_logs, @total_count, _ = Reposync::GetLogsService.call(nil, params[:reposync_branch_ids], page, limit)
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
def sync_repository_params
|
|
||||||
params.permit(:type, :external_token, :external_repo_address, :sync_granularity, :external_branch_name, :gitlink_branch_name, :first_sync_direction)
|
|
||||||
end
|
|
||||||
|
|
||||||
def sync_repository_update_params
|
|
||||||
params.permit(:external_token, :external_repo_address)
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
|
@ -1,13 +1,10 @@
|
||||||
class Api::V1::Projects::TagsController < Api::V1::BaseController
|
class Api::V1::Projects::TagsController < Api::V1::BaseController
|
||||||
before_action :require_public_and_member_above, only: [:index, :show]
|
before_action :require_public_and_member_above, only: [:index]
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@release_tags = @repository.version_releases.pluck(:tag_name)
|
@release_tags = @repository.version_releases.pluck(:tag_name)
|
||||||
@result_object = Api::V1::Projects::Tags::ListService.call(@project, {page: page, limit: limit}, current_user&.gitea_token)
|
@result_object = Api::V1::Projects::Tags::ListService.call(@project, {page: page, limit: limit}, current_user&.gitea_token)
|
||||||
end
|
puts @result_object
|
||||||
|
|
||||||
def show
|
|
||||||
@result_object = Api::V1::Projects::Tags::GetService.call(@project, params[:name], current_user&.gitea_token)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
before_action :require_operate_above, only: [:destroy]
|
before_action :require_operate_above, only: [:destroy]
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
class Api::V1::ProjectsController < Api::V1::BaseController
|
class Api::V1::ProjectsController < Api::V1::BaseController
|
||||||
before_action :require_public_and_member_above, only: [:show, :compare, :blame, :sonar_search]
|
before_action :require_public_and_member_above, only: [:show, :compare, :blame]
|
||||||
|
|
||||||
def index
|
def index
|
||||||
render_ok
|
render_ok
|
||||||
|
@ -9,7 +9,6 @@ class Api::V1::ProjectsController < Api::V1::BaseController
|
||||||
@result_object = Api::V1::Projects::GetService.call(@project, current_user.gitea_token)
|
@result_object = Api::V1::Projects::GetService.call(@project, current_user.gitea_token)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
def compare
|
def compare
|
||||||
@result_object = Api::V1::Projects::CompareService.call(@project, params[:from], params[:to], current_user&.gitea_token)
|
@result_object = Api::V1::Projects::CompareService.call(@project, params[:from], params[:to], current_user&.gitea_token)
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,208 +0,0 @@
|
||||||
class Api::V1::SonarqubesController < Api::V1::BaseController
|
|
||||||
before_action :load_repository
|
|
||||||
include Repository::LanguagesPercentagable
|
|
||||||
include SonarService
|
|
||||||
|
|
||||||
def sonar_initialize
|
|
||||||
gitea_params = { has_actions: params[:has_actions] == 'true' ? true :false }
|
|
||||||
gitea_setting = Gitea::Repository::UpdateService.call(@owner, @project.identifier, gitea_params)
|
|
||||||
if gitea_setting['has_actions'] == true
|
|
||||||
Gitea::Repository::ActionSecretsService.new(@owner, @project.identifier, 'SONAR_HOST_URL', Rails.application.config_for(:configuration)['sonarqube']['url'] ).call
|
|
||||||
Gitea::Repository::ActionSecretsService.new(@owner, @project.identifier, 'SONAR_TOKEN', Rails.application.config_for(:configuration)['sonarqube']['secret'] ).call
|
|
||||||
else
|
|
||||||
Gitea::Repository::ActionSecretsService.new(@owner, @project.identifier, 'SONAR_HOST_URL', Rails.application.config_for(:configuration)['sonarqube']['url'] ).destroy
|
|
||||||
Gitea::Repository::ActionSecretsService.new(@owner, @project.identifier, 'SONAR_TOKEN', Rails.application.config_for(:configuration)['sonarqube']['secret'] ).destroy
|
|
||||||
end
|
|
||||||
@project.update(gitea_params)
|
|
||||||
render_ok
|
|
||||||
end
|
|
||||||
|
|
||||||
def insert_file
|
|
||||||
checkout_url = 'https://gitlink.org.cn/KingChan/checkout@v4'
|
|
||||||
scanner_url = 'https://gitlink.org.cn/KingChan/sonarqube-scan-action@master'
|
|
||||||
doxygen_url = "https://gitlink.gitlink.net"
|
|
||||||
begin
|
|
||||||
config = Rails.application.config_for(:configuration)
|
|
||||||
sonarqube_config = config.dig('sonarqube')
|
|
||||||
|
|
||||||
if sonarqube_config.present? && sonarqube_config['checkout'].present?
|
|
||||||
checkout_url = sonarqube_config['checkout']
|
|
||||||
end
|
|
||||||
if sonarqube_config.present? && sonarqube_config['scanner'].present?
|
|
||||||
scanner_url = sonarqube_config['scanner']
|
|
||||||
end
|
|
||||||
if sonarqube_config.present? && sonarqube_config['doxygen'].present?
|
|
||||||
doxygen_url = sonarqube_config['doxygen']
|
|
||||||
end
|
|
||||||
raise 'sonar config missing' if sonarqube_config.blank?
|
|
||||||
rescue => ex
|
|
||||||
raise ex if Rails.env.production?
|
|
||||||
|
|
||||||
puts %Q{\033[33m [warning] soanrqube config or configuration.yml missing,
|
|
||||||
please add it or execute 'cp config/configuration.yml.example config/configuration.yml' \033[0m}
|
|
||||||
end
|
|
||||||
|
|
||||||
sonar_scanner_content = {
|
|
||||||
filepath: '.gitea/workflows/SonarScanner.yaml',
|
|
||||||
branch: params[:branch],
|
|
||||||
new_branch: nil,
|
|
||||||
content: "
|
|
||||||
on:
|
|
||||||
# Trigger analysis when pushing to your main branches, and when creating a pull request.
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
- master
|
|
||||||
- develop
|
|
||||||
- 'releases/**'
|
|
||||||
pull_request:
|
|
||||||
types: [opened, synchronize, reopened]
|
|
||||||
|
|
||||||
name: Main Workflow
|
|
||||||
jobs:
|
|
||||||
sonarqube:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: #{checkout_url}
|
|
||||||
with:
|
|
||||||
# Disabling shallow clones is recommended for improving the relevancy of reporting
|
|
||||||
fetch-depth: 0
|
|
||||||
- name: curl doxygen
|
|
||||||
run: |
|
|
||||||
curl -X GET #{doxygen_url}/generate?repo=#{@project.repository.url}
|
|
||||||
- name: SonarQube Scan
|
|
||||||
uses: #{scanner_url}
|
|
||||||
env:
|
|
||||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
|
||||||
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
|
|
||||||
",
|
|
||||||
message: 'Add .gitea/workflows/SonarScanner.yaml',
|
|
||||||
committer: {
|
|
||||||
email: @owner.mail,
|
|
||||||
name: @owner.login
|
|
||||||
},
|
|
||||||
identifier: @project.identifier
|
|
||||||
}
|
|
||||||
@path = GiteaService.gitea_config[:domain]+"/#{@project.owner.login}/#{@project.identifier}/raw/branch/#{params[:branch]}/"
|
|
||||||
sonar_scanner_exit = Repositories::EntriesInteractor.call(@owner, @project.identifier, '.gitea/workflows/SonarScanner.yaml', ref: params[:branch])
|
|
||||||
if sonar_scanner_exit.success?
|
|
||||||
Gitea::UpdateFileInteractor.call(@owner.gitea_token, @owner.login, sonar_scanner_content.merge(sha:sonar_scanner_exit.result['sha']))
|
|
||||||
else
|
|
||||||
sonar_scanner_content[:content] = Base64.strict_encode64(sonar_scanner_content[:content])
|
|
||||||
Gitea::CreateFileInteractor.call(@owner.gitea_token, @owner.login, sonar_scanner_content)
|
|
||||||
end
|
|
||||||
|
|
||||||
sonar_content = build_sonar_content(params[:owner], @project.id, languages_precentagable.keys)
|
|
||||||
|
|
||||||
sonar_project_content = {
|
|
||||||
filepath: 'sonar-project.properties',
|
|
||||||
branch: params[:branch],
|
|
||||||
new_branch: nil,
|
|
||||||
"content": sonar_content,
|
|
||||||
"message": 'Add sonar-project.properties',
|
|
||||||
committer: {
|
|
||||||
email: @owner.mail,
|
|
||||||
name: @owner.login
|
|
||||||
},
|
|
||||||
identifier: @project.identifier
|
|
||||||
}
|
|
||||||
|
|
||||||
sonar_project_exit = Repositories::EntriesInteractor.call(@owner, @project.identifier, 'sonar-project.properties', ref: params[:branch])
|
|
||||||
if sonar_project_exit.success?
|
|
||||||
Gitea::UpdateFileInteractor.call(@owner.gitea_token, @owner.login, sonar_project_content.merge(sha:sonar_project_exit.result['sha']))
|
|
||||||
else
|
|
||||||
sonar_project_content[:content] = Base64.strict_encode64(sonar_project_content[:content])
|
|
||||||
Gitea::CreateFileInteractor.call(@owner.gitea_token, @owner.login, sonar_project_content)
|
|
||||||
end
|
|
||||||
render_ok
|
|
||||||
end
|
|
||||||
|
|
||||||
def issues_search
|
|
||||||
params_data = {
|
|
||||||
components: "#{params[:owner]}-#{@project.id}",
|
|
||||||
s: params[:s],
|
|
||||||
impactSoftwareQualities: params[:impactSoftwareQualities],
|
|
||||||
issueStatuses: params[:issueStatuses],
|
|
||||||
ps: params[:ps],
|
|
||||||
p: params[:p],
|
|
||||||
facets: params[:facets],
|
|
||||||
additionalFields: params[:additionalFields],
|
|
||||||
timeZone: params[:timeZone],
|
|
||||||
types: params[:types],
|
|
||||||
impactSeverities: params[:impactSeverities],
|
|
||||||
tags: params[:tags]
|
|
||||||
}
|
|
||||||
data = Sonarqube.client.get('/api/issues/search', query: params_data)
|
|
||||||
render_ok data
|
|
||||||
end
|
|
||||||
|
|
||||||
def ce_component
|
|
||||||
params_data = {
|
|
||||||
components: "#{params[:owner]}-#{@project.id}",
|
|
||||||
}
|
|
||||||
data = Sonarqube.client.get('/api/ce/component', query: params_data)
|
|
||||||
render_ok data
|
|
||||||
end
|
|
||||||
|
|
||||||
def sources_issue_snippet
|
|
||||||
params_data = {
|
|
||||||
issueKey: params[:issueKey]
|
|
||||||
}
|
|
||||||
data = Sonarqube.client.get('/api/sources/issue_snippets', query: params_data)
|
|
||||||
render_ok data
|
|
||||||
end
|
|
||||||
|
|
||||||
def rules_show
|
|
||||||
params_data = {
|
|
||||||
key: params[:key]
|
|
||||||
}
|
|
||||||
data = Sonarqube.client.get('/api/rules/show', query: params_data)
|
|
||||||
render_ok data
|
|
||||||
end
|
|
||||||
|
|
||||||
def doxygen_url
|
|
||||||
config = Rails.application.config_for(:configuration)
|
|
||||||
sonarqube_config = config.dig('sonarqube')
|
|
||||||
doxygen_url = sonarqube_config['doxygen']
|
|
||||||
data = {doxygen_url: "#{doxygen_url}/files/#{@project.owner.login}/#{@project.identifier}/html/"}
|
|
||||||
render_ok data
|
|
||||||
end
|
|
||||||
|
|
||||||
def analyze_doxygen
|
|
||||||
config = Rails.application.config_for(:configuration)
|
|
||||||
sonarqube_config = config.dig('sonarqube')
|
|
||||||
doxygen_url = sonarqube_config['doxygen']
|
|
||||||
|
|
||||||
url = "#{doxygen_url}/files/#{@project.owner.login}/#{@project.identifier}/html/analyze_doxygen.json"
|
|
||||||
uri = URI.parse(url)
|
|
||||||
response = Net::HTTP.get_response(uri)
|
|
||||||
if response.code.to_i != 200
|
|
||||||
puts "======= 接口请求失败!"
|
|
||||||
data = { data: nil, msg: '文件不存在' }
|
|
||||||
else
|
|
||||||
data = { data: JSON.parse(response.body), msg: 'ok' }
|
|
||||||
end
|
|
||||||
render_ok data
|
|
||||||
end
|
|
||||||
|
|
||||||
def measures_search_history
|
|
||||||
params_data = {
|
|
||||||
from: params[:form],
|
|
||||||
component: "#{params[:owner]}-#{@project.id}",
|
|
||||||
metrics: params[:metrics],
|
|
||||||
ps: params[:ps]
|
|
||||||
}
|
|
||||||
data = Sonarqube.client.get('/api/measures/search_history', query: params_data)
|
|
||||||
render_ok data
|
|
||||||
end
|
|
||||||
|
|
||||||
def measures_component
|
|
||||||
params_data = {
|
|
||||||
component: "#{params[:owner]}-#{@project.id}",
|
|
||||||
additionalFields: params[:additionalFields],
|
|
||||||
metricKeys: params[:metricKeys]
|
|
||||||
}
|
|
||||||
data = Sonarqube.client.get('/api/measures/component', query: params_data)
|
|
||||||
render_ok data
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,23 +0,0 @@
|
||||||
class Api::V1::Users::HomeTopSettingsController < Api::V1::BaseController
|
|
||||||
|
|
||||||
before_action :load_observe_user
|
|
||||||
before_action :check_auth_for_observe_user
|
|
||||||
|
|
||||||
def create
|
|
||||||
@result = Api::V1::Users::HomeTopSettings::CreateService.call(@observe_user, home_top_setting_params)
|
|
||||||
return render_error("置顶失败.") if @result.nil?
|
|
||||||
return render_ok
|
|
||||||
end
|
|
||||||
|
|
||||||
def cancel
|
|
||||||
@result = Api::V1::Users::HomeTopSettings::DeleteService.call(@observe_user, home_top_setting_params)
|
|
||||||
return render_error("取消置顶失败.") if @result.nil?
|
|
||||||
return render_ok
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
def home_top_setting_params
|
|
||||||
params.permit(:top_type, :top_id)
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
|
@ -8,6 +8,6 @@ class Api::V1::Users::ProjectsController < Api::V1::BaseController
|
||||||
|
|
||||||
private
|
private
|
||||||
def query_params
|
def query_params
|
||||||
params.permit(:category, :is_public, :project_type, :sort_by, :sort_direction, :search, :start_at, :end_at)
|
params.permit(:category, :is_public, :project_type, :sort_by, :sort_direction, :search)
|
||||||
end
|
end
|
||||||
end
|
end
|
|
@ -1,5 +1,4 @@
|
||||||
class Api::V1::UsersController < Api::V1::BaseController
|
class Api::V1::UsersController < Api::V1::BaseController
|
||||||
include AesCryptHelper
|
|
||||||
|
|
||||||
before_action :load_observe_user, except: [:check_user_id, :check_user_login]
|
before_action :load_observe_user, except: [:check_user_id, :check_user_login]
|
||||||
before_action :check_auth_for_observe_user, except: [:check_user_id, :check_user_login]
|
before_action :check_auth_for_observe_user, except: [:check_user_id, :check_user_login]
|
||||||
|
@ -54,7 +53,7 @@ class Api::V1::UsersController < Api::V1::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_password
|
def check_password
|
||||||
password = decrypt(params[:password]) rescue params[:password].to_s
|
password = params[:password]
|
||||||
return tip_exception(-5, "8~16位密码,支持字母数字和符号") unless password =~ CustomRegexp::PASSWORD
|
return tip_exception(-5, "8~16位密码,支持字母数字和符号") unless password =~ CustomRegexp::PASSWORD
|
||||||
return tip_exception(-5, "密码错误") unless @observe_user.check_password?(password)
|
return tip_exception(-5, "密码错误") unless @observe_user.check_password?(password)
|
||||||
render_ok
|
render_ok
|
||||||
|
@ -116,29 +115,4 @@ class Api::V1::UsersController < Api::V1::BaseController
|
||||||
return render_error('更改手机号失败!')
|
return render_error('更改手机号失败!')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
def check_user_can_delete
|
|
||||||
org_ids = TeamUser.where(user_id: @observe_user.id).pluck(:organization_id) | OrganizationUser.where(user_id: @observe_user.id).pluck(:organization_id)
|
|
||||||
org_count = TeamUser.where(organization_id: org_ids).where(user_id: @observe_user.id).joins(:team).where(teams: {authorize: %w(owner)}).count
|
|
||||||
project_count = Project.where(user_id: @observe_user.id).count
|
|
||||||
render_ok({ can_delete: org_count == 0 && project_count == 0, org_count: org_count, project_count: project_count })
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
def destroy
|
|
||||||
password = decrypt(params[:password]) rescue params[:password].to_s
|
|
||||||
return tip_exception(-1, "密码不正确.") unless @observe_user.check_password?(password)
|
|
||||||
org_ids = TeamUser.where(user_id: @observe_user.id).pluck(:organization_id) | OrganizationUser.where(user_id: @observe_user.id).pluck(:organization_id)
|
|
||||||
org_count = TeamUser.where(organization_id: org_ids).where(user_id: @observe_user.id).joins(:team).where(teams: {authorize: %w(owner)}).count
|
|
||||||
project_count = Project.where(user_id: @observe_user.id).count
|
|
||||||
return tip_exception(-1, "当前账号名下存在拥有的组织/代码库,请先删除或转让后再尝试注销操作.") if org_count > 0 || project_count > 0
|
|
||||||
UserAction.create(action_id: @observe_user.id, action_type: "DestroyUser", user_id: @observe_user.id, :ip => request.remote_ip, data_bank: @observe_user.attributes.to_json, memo: params[:memo])
|
|
||||||
@result_object = Api::V1::Users::DeleteUserService.call(@observe_user)
|
|
||||||
if @result_object
|
|
||||||
return render_ok
|
|
||||||
else
|
|
||||||
return render_error('删除失败!')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
|
@ -78,10 +78,6 @@ class ApplicationController < ActionController::Base
|
||||||
User.current.admin? || User.current.business?
|
User.current.admin? || User.current.business?
|
||||||
end
|
end
|
||||||
|
|
||||||
def admin_or_glcc_admin?
|
|
||||||
User.current.admin? || User.current.glcc_admin?
|
|
||||||
end
|
|
||||||
|
|
||||||
# 判断用户的邮箱或者手机是否可用
|
# 判断用户的邮箱或者手机是否可用
|
||||||
# params[:type] 1: 注册;2:忘记密码;3:绑定
|
# params[:type] 1: 注册;2:忘记密码;3:绑定
|
||||||
def check_mail_and_phone_valid login, type
|
def check_mail_and_phone_valid login, type
|
||||||
|
@ -199,10 +195,6 @@ class ApplicationController < ActionController::Base
|
||||||
normal_status(403, "") unless admin_or_business?
|
normal_status(403, "") unless admin_or_business?
|
||||||
end
|
end
|
||||||
|
|
||||||
def require_glcc_admin
|
|
||||||
normal_status(403, "") unless admin_or_glcc_admin?
|
|
||||||
end
|
|
||||||
|
|
||||||
# 前端会捕捉401,弹登录弹框
|
# 前端会捕捉401,弹登录弹框
|
||||||
# 未授权的捕捉407,弹试用申请弹框
|
# 未授权的捕捉407,弹试用申请弹框
|
||||||
def require_login
|
def require_login
|
||||||
|
@ -210,10 +202,6 @@ class ApplicationController < ActionController::Base
|
||||||
tip_exception(401, "请登录后再操作") unless User.current.logged?
|
tip_exception(401, "请登录后再操作") unless User.current.logged?
|
||||||
end
|
end
|
||||||
|
|
||||||
def require_referer
|
|
||||||
tip_exception(403, "你没有权限访问") if request.host.present? && !request.referer.to_s.include?(request.host.to_s.gsub("www.",""))
|
|
||||||
end
|
|
||||||
|
|
||||||
def require_login_or_token
|
def require_login_or_token
|
||||||
if params[:token].present?
|
if params[:token].present?
|
||||||
user = User.try_to_autologin(params[:token])
|
user = User.try_to_autologin(params[:token])
|
||||||
|
@ -234,11 +222,11 @@ class ApplicationController < ActionController::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def require_profile_completed
|
def require_profile_completed
|
||||||
tip_exception(411, "请完善资料后再操作") unless User.current.profile_is_completed?
|
# tip_exception(411, "请完善资料后再操作") unless User.current.profile_is_completed?
|
||||||
end
|
end
|
||||||
|
|
||||||
def require_user_profile_completed(user)
|
def require_user_profile_completed(user)
|
||||||
tip_exception(412, "请用户完善资料后再操作") unless user.profile_is_completed?
|
# tip_exception(412, "请用户完善资料后再操作") unless user.profile_is_completed?
|
||||||
end
|
end
|
||||||
|
|
||||||
# 异常提醒
|
# 异常提醒
|
||||||
|
@ -330,19 +318,19 @@ class ApplicationController < ActionController::Base
|
||||||
User.current = find_current_user
|
User.current = find_current_user
|
||||||
uid_logger("user_setup: " + (User.current.logged? ? "#{User.current.try(:login)} (id=#{User.current.try(:id)})" : "anonymous"))
|
uid_logger("user_setup: " + (User.current.logged? ? "#{User.current.try(:login)} (id=#{User.current.try(:id)})" : "anonymous"))
|
||||||
|
|
||||||
# # 开放课程通过链接访问的用户
|
# 开放课程通过链接访问的用户
|
||||||
# if !User.current.logged? && !params[:chinaoocTimestamp].blank? && !params[:websiteName].blank? && !params[:chinaoocKey].blank?
|
if !User.current.logged? && !params[:chinaoocTimestamp].blank? && !params[:websiteName].blank? && !params[:chinaoocKey].blank?
|
||||||
# content = "#{OPENKEY}#{params[:websiteName]}#{params[:chinaoocTimestamp]}"
|
content = "#{OPENKEY}#{params[:websiteName]}#{params[:chinaoocTimestamp]}"
|
||||||
#
|
|
||||||
# if Digest::MD5.hexdigest(content) == params[:chinaoocKey]
|
if Digest::MD5.hexdigest(content) == params[:chinaoocKey]
|
||||||
# user = open_class_user
|
user = open_class_user
|
||||||
# if user
|
if user
|
||||||
# start_user_session(user)
|
start_user_session(user)
|
||||||
# set_autologin_cookie(user)
|
set_autologin_cookie(user)
|
||||||
# end
|
end
|
||||||
# User.current = user
|
User.current = user
|
||||||
# end
|
end
|
||||||
# end
|
end
|
||||||
|
|
||||||
if !User.current.logged? && Rails.env.development?
|
if !User.current.logged? && Rails.env.development?
|
||||||
user = User.find 1
|
user = User.find 1
|
||||||
|
@ -375,14 +363,15 @@ class ApplicationController < ActionController::Base
|
||||||
uid_logger("user setup start: session[:user_id] is #{session[:user_id]}")
|
uid_logger("user setup start: session[:user_id] is #{session[:user_id]}")
|
||||||
uid_logger("0000000000000user setup start: default_yun_session is #{default_yun_session}, session[:current_user_id] is #{session[:"#{default_yun_session}"]}")
|
uid_logger("0000000000000user setup start: default_yun_session is #{default_yun_session}, session[:current_user_id] is #{session[:"#{default_yun_session}"]}")
|
||||||
current_domain_session = session[:"#{default_yun_session}"]
|
current_domain_session = session[:"#{default_yun_session}"]
|
||||||
autologin_user = try_to_autologin
|
if current_domain_session
|
||||||
uid_logger("user setup start: autologin_user is #{autologin_user}")
|
# existing session
|
||||||
# 多浏览器退出账号时,token不存在处理
|
User.current = (User.active.find(current_domain_session) rescue nil)
|
||||||
if current_domain_session && autologin_user.nil?
|
elsif autologin_user = try_to_autologin
|
||||||
autologin_user = (User.active.find(current_domain_session) rescue nil)
|
autologin_user
|
||||||
set_autologin_cookie(autologin_user) if autologin_user.present?
|
elsif params[:format] == 'atom' && params[:key] && request.get? && accept_rss_auth?
|
||||||
|
# RSS key authentication does not start a session
|
||||||
|
User.find_by_rss_key(params[:key])
|
||||||
end
|
end
|
||||||
autologin_user
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def try_to_autologin
|
def try_to_autologin
|
||||||
|
@ -421,6 +410,24 @@ class ApplicationController < ActionController::Base
|
||||||
"#{edu_setting('git_address_domain')}/#{repo_path}"
|
"#{edu_setting('git_address_domain')}/#{repo_path}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# 通关后,把最后一次成功的代码存到数据库
|
||||||
|
# type 0 创始内容, 1 最新内容
|
||||||
|
# def game_passed_code(path, myshixun, game_id)
|
||||||
|
# # 如果代码窗口是隐藏的,则不用保存代码
|
||||||
|
# return if myshixun.shixun.hide_code || myshixun.shixun.vnc
|
||||||
|
# file_content = git_fle_content myshixun.repo_path, path
|
||||||
|
# #unless file_content.present?
|
||||||
|
# # raise("获取文件代码异常")
|
||||||
|
# #end
|
||||||
|
# logger.info("#######game_id:#{game_id}, file_content:#{file_content}")
|
||||||
|
# game_code = GameCode.where(:game_id => game_id, :path => path).first
|
||||||
|
# if game_code.nil?
|
||||||
|
# GameCode.create!(:game_id => game_id, :new_code => file_content, :path => path)
|
||||||
|
# else
|
||||||
|
# game_code.update_attributes!(:new_code => file_content)
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
|
||||||
# Post请求
|
# Post请求
|
||||||
def uri_post(uri, params)
|
def uri_post(uri, params)
|
||||||
begin
|
begin
|
||||||
|
@ -512,6 +519,112 @@ class ApplicationController < ActionController::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
# 实训主类别列表,自带描述
|
||||||
|
def shixun_main_type
|
||||||
|
list = []
|
||||||
|
mirrors = MirrorRepository.select([:id, :type_name, :description, :name]).published_main_mirror
|
||||||
|
mirrors.try(:each) do |mirror|
|
||||||
|
list << {id: mirror.id, type_name: mirror.type_name, description: mirror.try(:description), mirror_name: mirror.name}
|
||||||
|
end
|
||||||
|
list
|
||||||
|
end
|
||||||
|
|
||||||
|
# 小类别列表
|
||||||
|
def shixun_small_type
|
||||||
|
list = []
|
||||||
|
mirrors = MirrorRepository.select([:id, :type_name, :description, :name]).published_small_mirror
|
||||||
|
mirrors.try(:each) do |mirror|
|
||||||
|
list << {id: mirror.id, type_name: mirror.type_name, description: mirror.description, mirror_name: mirror.name}
|
||||||
|
end
|
||||||
|
list
|
||||||
|
end
|
||||||
|
|
||||||
|
def container_limit(mirror_repositories)
|
||||||
|
container = []
|
||||||
|
mirror_repositories.each do |mr|
|
||||||
|
if mr.name.present?
|
||||||
|
container << {:image => mr.name, :cpuLimit => mr.cpu_limit, :memoryLimit => "#{mr.memory_limit}M", :type => mr.try(:main_type) == "1" ? "main" : "sub"}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
container.to_json
|
||||||
|
end
|
||||||
|
|
||||||
|
# 实训中间层pod配置
|
||||||
|
def shixun_container_limit shixun
|
||||||
|
container = []
|
||||||
|
shixun.shixun_service_configs.each do |config|
|
||||||
|
mirror = config.mirror_repository
|
||||||
|
if mirror.name.present?
|
||||||
|
# 资源限制没有就传默认值。
|
||||||
|
cpu_limit = config.cpu_limit.presence || 1
|
||||||
|
cpu_request = config.lower_cpu_limit.presence || 0.1
|
||||||
|
memory_limit = config.memory_limit.presence || 1024
|
||||||
|
request_limit = config.request_limit.presence || 10
|
||||||
|
resource_limit = config.resource_limit.presence || 10000
|
||||||
|
container << {:image => mirror.name,
|
||||||
|
:cpuLimit => cpu_limit,
|
||||||
|
:cpuRequest => cpu_request,
|
||||||
|
:memoryLimit => "#{memory_limit}M",
|
||||||
|
:memoryRequest => "#{request_limit}M",
|
||||||
|
:resourceLimit => "#{resource_limit}K",
|
||||||
|
:type => mirror.try(:main_type) == "1" ? "main" : "sub"}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
container.to_json
|
||||||
|
end
|
||||||
|
|
||||||
|
# 毕设任务列表的赛选
|
||||||
|
def course_work(task, **option)
|
||||||
|
logger.info("#############{option}")
|
||||||
|
course = task.course
|
||||||
|
work_list = task.graduation_works.includes(user: [:user_extension])
|
||||||
|
# 教师评阅搜索 0: 未评, 1 已评
|
||||||
|
if option[:teacher_comment]
|
||||||
|
graduation_work_ids = GraduationWorkScore.where(graduation_work_id: work_list.map(&:id)).pluck(:graduation_work_id)
|
||||||
|
if option[:teacher_comment].zero?
|
||||||
|
work_list = work_list.where.not(id: graduation_work_ids)
|
||||||
|
elsif option[:teacher_comment] == 1
|
||||||
|
work_list = work_list.where(id: graduation_work_ids).where.not(work_status: 0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# 作品状态 0: 未提交, 1 按时提交, 2 延迟提交
|
||||||
|
if option[:task_status]
|
||||||
|
work_list = work_list.where(work_status: option[:task_status])
|
||||||
|
end
|
||||||
|
|
||||||
|
# 分班情况
|
||||||
|
if option[:course_group]
|
||||||
|
group_user_ids = course.course_members.where(course_group_id: option[:course_group]).pluck(:user_id)
|
||||||
|
# 有分组只可能是老师身份查看列表
|
||||||
|
work_list = work_list.where(user_id: group_user_ids)
|
||||||
|
end
|
||||||
|
|
||||||
|
# 只看我的交叉评阅
|
||||||
|
if option[:cross_comment]
|
||||||
|
graduation_work_id = task.graduation_work_comment_assignations.where(:user_id => current_user.id)
|
||||||
|
.pluck(:graduation_work_id).uniq if task.graduation_work_comment_assignations
|
||||||
|
work_list = work_list.where(id: graduation_work_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
# 输入姓名和学号搜索
|
||||||
|
# TODO user_extension 如果修改 请调整
|
||||||
|
if option[:search]
|
||||||
|
work_list = work_list.joins(user: :user_extension).where("concat(lastname, firstname) like ?
|
||||||
|
or student_id like ?", "%#{option[:search]}%", "%#{option[:search]}%")
|
||||||
|
end
|
||||||
|
|
||||||
|
# 排序
|
||||||
|
rorder = UserExtension.column_names.include?(option[:order]) ? option[:order] : "updated_at"
|
||||||
|
b_order = %w(desc asc).include?(option[:b_order]) ? option[:b_order] : "desc"
|
||||||
|
if rorder == "created_at" || rorder == "work_score"
|
||||||
|
work_list = work_list.order("graduation_works.#{rorder} #{b_order}")
|
||||||
|
elsif rorder == "student_id"
|
||||||
|
work_list = work_list.joins(user: :user_extension).order("user_extensions.#{rorder} #{b_order}")
|
||||||
|
end
|
||||||
|
work_list
|
||||||
|
end
|
||||||
|
|
||||||
def strip_html(text, len=0, endss="...")
|
def strip_html(text, len=0, endss="...")
|
||||||
ss = ""
|
ss = ""
|
||||||
if !text.nil? && text.length>0
|
if !text.nil? && text.length>0
|
||||||
|
@ -602,7 +715,7 @@ class ApplicationController < ActionController::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def find_user_with_id
|
def find_user_with_id
|
||||||
@user = User.find_by(type: 'User', id: params[:user_id])
|
@user = User.find_by_id params[:user_id]
|
||||||
# render_not_found("未找到’#{params[:login]}’相关的用户") unless @user
|
# render_not_found("未找到’#{params[:login]}’相关的用户") unless @user
|
||||||
render_error("未找到相关的用户") unless @user
|
render_error("未找到相关的用户") unless @user
|
||||||
end
|
end
|
||||||
|
@ -1052,46 +1165,15 @@ class ApplicationController < ActionController::Base
|
||||||
|
|
||||||
# 接口限流,请求量大有性能问题
|
# 接口限流,请求量大有性能问题
|
||||||
def request_limit
|
def request_limit
|
||||||
white_list_ip = ["106.75.110.152"]
|
record_count = Rails.cache.read("request/#{controller_name}/#{Time.now.strftime('%Y%m%d%H%M')}/#{request.remote_ip}")
|
||||||
unless white_list_ip.include?(request.remote_ip)
|
|
||||||
record_count = Rails.cache.read("request/#{controller_name}/#{Time.now.strftime('%Y%m%d%H')}/#{request.remote_ip}")
|
|
||||||
if record_count.present?
|
|
||||||
record_count = record_count + 1
|
|
||||||
else
|
|
||||||
record_count = 1
|
|
||||||
end
|
|
||||||
Rails.logger.info("请求太快,请稍后再试。#{controller_name}::#{request.remote_ip}") if record_count > 200
|
|
||||||
tip_exception("请求太快,请稍后再试。") if record_count > 200
|
|
||||||
|
|
||||||
Rails.cache.write("request/#{controller_name}/#{Time.now.strftime('%Y%m%d%H')}/#{request.remote_ip}", record_count, expires_in: 1.hour)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def check_batch_requests
|
|
||||||
check_key = "request.remote_ip:#{request.remote_ip}"
|
|
||||||
result = Rails.cache.read(check_key)
|
|
||||||
if result.present?
|
|
||||||
if result.to_i > 100
|
|
||||||
tip_exception(401, '暂时无法请求,请稍后再试')
|
|
||||||
else
|
|
||||||
Rails.cache.write(check_key, result.to_i + 1)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
Rails.cache.write(check_key, 1, expires_in: 1.hour)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def request_raw_limit
|
|
||||||
record_count = Rails.cache.read("request/#{request.path}/#{Time.now.strftime('%Y%m%d%H')}}")
|
|
||||||
if record_count.present?
|
if record_count.present?
|
||||||
record_count = record_count + 1
|
record_count = record_count + 1
|
||||||
else
|
else
|
||||||
record_count = 1
|
record_count = 1
|
||||||
end
|
end
|
||||||
Rails.logger.info("请求太快,请稍后再试。#{request.path}") if record_count > 1000
|
tip_exception("请求太快,请稍后再试。") if record_count > 100
|
||||||
tip_exception("请求太快,请稍后再试。") if record_count > 1000
|
|
||||||
|
|
||||||
Rails.cache.write("request/#{request.path}/#{Time.now.strftime('%Y%m%d%H')}}", record_count, expires_in: 1.hour)
|
Rails.cache.write("request/#{controller_name}/#{Time.now.strftime('%Y%m%d%H%M')}/#{request.remote_ip}", record_count, expires_in: 1.minute)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -30,33 +30,24 @@ class AttachmentsController < ApplicationController
|
||||||
|
|
||||||
|
|
||||||
def get_file
|
def get_file
|
||||||
Rails.logger.info("request.host===#{request.host},request.referer===#{request.referer}")
|
|
||||||
tip_exception(403, "你没有权限访问") if request.host.present? && !request.referer.to_s.include?(request.host.to_s.gsub("www.",""))
|
|
||||||
normal_status(-1, "参数缺失") if params[:download_url].blank?
|
normal_status(-1, "参数缺失") if params[:download_url].blank?
|
||||||
url = base_url.starts_with?("https:") ? params[:download_url].to_s.gsub("http:", "https:") : params[:download_url].to_s
|
url = base_url.starts_with?("https:") ? params[:download_url].to_s.gsub("http:", "https:") : params[:download_url].to_s
|
||||||
md5_file = Digest::MD5.hexdigest(params[:download_url])
|
|
||||||
FileUtils.mkdir_p("#{Rails.root}#{EduSetting.get("attachment_folder")}gitea/") unless Dir.exists?("#{Rails.root}#{EduSetting.get("attachment_folder")}gitea/")
|
|
||||||
tmp_path = "#{Rails.root}#{EduSetting.get("attachment_folder")}gitea/#{Time.now.strftime('%Y%m%d')}-#{md5_file}"
|
|
||||||
if url.starts_with?(base_url) && !url.starts_with?("#{base_url}/repo")
|
if url.starts_with?(base_url) && !url.starts_with?("#{base_url}/repo")
|
||||||
domain = GiteaService.gitea_config[:domain]
|
domain = GiteaService.gitea_config[:domain]
|
||||||
api_url = GiteaService.gitea_config[:base_url]
|
api_url = GiteaService.gitea_config[:base_url]
|
||||||
url = ("/repos"+url.split(base_url + "/api")[1])
|
url = ("/repos"+url.split(base_url + "/api")[1])
|
||||||
filepath, ref = url.split("/")[-1].split("?")
|
filepath, ref = url.split("/")[-1].split("?")
|
||||||
url.gsub!(url.split("/")[-1], '')
|
url.gsub!(url.split("/")[-1], '')
|
||||||
# Rails.logger.info("url===#{url}")
|
Rails.logger.info("url===#{url}")
|
||||||
Rails.logger.info(filepath)
|
request_url = [domain, api_url, URI.encode(url), CGI.escape(filepath), "?ref=#{CGI.escape(ref.split('ref=')[1])}&access_token=#{User.where(admin: true).take&.gitea_token}"].join
|
||||||
ref = ref.blank? ? "" : URI.escape(ref.split('ref=')[1])
|
|
||||||
request_url = [domain, api_url, URI.encode(url), URI.escape(filepath), "?ref=#{ref}&access_token=#{User.where(admin: true).take&.gitea_token}"].join
|
|
||||||
Rails.logger.info("request_url===#{request_url}")
|
Rails.logger.info("request_url===#{request_url}")
|
||||||
File.delete(tmp_path) if File.exist?(tmp_path) # 删除之前的文件
|
response = Faraday.get(request_url)
|
||||||
Util.download_file(request_url, tmp_path)
|
|
||||||
filename = filepath
|
filename = filepath
|
||||||
else
|
else
|
||||||
File.delete(tmp_path) if File.exist?(tmp_path) # 删除之前的文件
|
response = Faraday.get(URI.encode(url))
|
||||||
Util.download_file(URI.encode(url), tmp_path)
|
|
||||||
filename = params[:download_url].to_s.split("/").pop()
|
filename = params[:download_url].to_s.split("/").pop()
|
||||||
end
|
end
|
||||||
send_file(tmp_path, filename: filename, type: "application/octet-stream", disposition: 'attachment')
|
send_data(response.body.force_encoding("UTF-8"), filename: filename, type: "application/octet-stream", disposition: 'attachment')
|
||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
|
@ -102,10 +93,6 @@ class AttachmentsController < ApplicationController
|
||||||
@attachment.author_id = current_user.id
|
@attachment.author_id = current_user.id
|
||||||
@attachment.disk_directory = month_folder
|
@attachment.disk_directory = month_folder
|
||||||
@attachment.cloud_url = remote_path
|
@attachment.cloud_url = remote_path
|
||||||
@attachment.uuid = SecureRandom.uuid
|
|
||||||
@attachment.description = params[:description]
|
|
||||||
@attachment.container_id = params[:container_id]
|
|
||||||
@attachment.container_type = params[:container_type]
|
|
||||||
@attachment.save!
|
@attachment.save!
|
||||||
else
|
else
|
||||||
logger.info "文件已存在,id = #{@attachment.id}, filename = #{@attachment.filename}"
|
logger.info "文件已存在,id = #{@attachment.id}, filename = #{@attachment.filename}"
|
||||||
|
@ -135,7 +122,7 @@ class AttachmentsController < ApplicationController
|
||||||
|
|
||||||
# 附件为视频时,点击播放
|
# 附件为视频时,点击播放
|
||||||
def preview_attachment
|
def preview_attachment
|
||||||
attachment = Attachment.where_id_or_uuid(params[:id]).first
|
attachment = Attachment.find_by(id: params[:id])
|
||||||
dir_path = "#{Rails.root}/public/preview"
|
dir_path = "#{Rails.root}/public/preview"
|
||||||
Dir.mkdir(dir_path) unless Dir.exist?(dir_path)
|
Dir.mkdir(dir_path) unless Dir.exist?(dir_path)
|
||||||
if params[:status] == "preview"
|
if params[:status] == "preview"
|
||||||
|
@ -155,14 +142,12 @@ class AttachmentsController < ApplicationController
|
||||||
|
|
||||||
private
|
private
|
||||||
def find_file
|
def find_file
|
||||||
tip_exception(404, "您访问的页面不存在或已被删除") if params[:id].blank?
|
|
||||||
@file =
|
@file =
|
||||||
if params[:type] == 'history'
|
if params[:type] == 'history'
|
||||||
AttachmentHistory.find params[:id]
|
AttachmentHistory.find params[:id]
|
||||||
else
|
else
|
||||||
Attachment.where_id_or_uuid(params[:id]).first
|
Attachment.find params[:id]
|
||||||
end
|
end
|
||||||
tip_exception(404, "您访问的页面不存在或已被删除") if @file.blank?
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def delete_file(file_path)
|
def delete_file(file_path)
|
||||||
|
@ -232,22 +217,18 @@ class AttachmentsController < ApplicationController
|
||||||
def attachment_candown
|
def attachment_candown
|
||||||
unless current_user.admin? || current_user.business?
|
unless current_user.admin? || current_user.business?
|
||||||
candown = true
|
candown = true
|
||||||
if @file.container && @file.uuid.nil?
|
if @file.container
|
||||||
if @file.container.is_a?(Issue)
|
if @file.container.is_a?(Issue)
|
||||||
project = @file.container.project
|
project = @file.container.project
|
||||||
candown = project.is_public || (current_user.logged? && project.member?(current_user))
|
candown = project.is_public || (current_user.logged? && project.member?(current_user))
|
||||||
elsif @file.container.is_a?(Journal)
|
elsif @file.container.is_a?(Journal)
|
||||||
project = @file.container.issue.project
|
project = @file.container.issue.project
|
||||||
candown = project.is_public || (current_user.logged? && project.member?(current_user))
|
candown = project.is_public || (current_user.logged? && project.member?(current_user))
|
||||||
elsif @file.container.is_a?(Project)
|
|
||||||
project = @file.container
|
|
||||||
candown = project.is_public || (current_user.logged? && project.member?(current_user))
|
|
||||||
else
|
else
|
||||||
project = nil
|
project = nil
|
||||||
end
|
end
|
||||||
tip_exception(403, "您没有权限进入") if project.present? && !candown
|
tip_exception(403, "您没有权限进入") if project.present? && !candown
|
||||||
end
|
end
|
||||||
tip_exception(403, "您没有权限查看") if @file.is_public == 0 && @file.author_id != current_user.id
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ class BindUsersController < ApplicationController
|
||||||
bind_user = User.try_to_login(params[:username], params[:password])
|
bind_user = User.try_to_login(params[:username], params[:password])
|
||||||
tip_exception '用户名或者密码错误' if bind_user.blank?
|
tip_exception '用户名或者密码错误' if bind_user.blank?
|
||||||
tip_exception '用户名或者密码错误' unless bind_user.check_password?(params[:password].to_s)
|
tip_exception '用户名或者密码错误' unless bind_user.check_password?(params[:password].to_s)
|
||||||
tip_exception '参数错误' unless ["qq", "wechat", "gitee", "github", "educoder", "acge"].include?(params[:type].to_s)
|
tip_exception '参数错误' unless ["qq", "wechat", "gitee", "github", "educoder"].include?(params[:type].to_s)
|
||||||
tip_exception '该账号已被绑定,请更换其他账号进行绑定' if bind_user.bind_open_user?(params[:type].to_s)
|
tip_exception '该账号已被绑定,请更换其他账号进行绑定' if bind_user.bind_open_user?(params[:type].to_s)
|
||||||
|
|
||||||
"OpenUsers::#{params[:type].to_s.capitalize}".constantize.create!(user: bind_user, uid: session[:unionid])
|
"OpenUsers::#{params[:type].to_s.capitalize}".constantize.create!(user: bind_user, uid: session[:unionid])
|
||||||
|
|
|
@ -19,23 +19,12 @@ class CommitLogsController < ApplicationController
|
||||||
params[:commits].each do |commit|
|
params[:commits].each do |commit|
|
||||||
commit_id = commit[:id]
|
commit_id = commit[:id]
|
||||||
message = commit[:message]
|
message = commit[:message]
|
||||||
commit_date = Time.parse(commit[:timestamp]) || Time.now
|
|
||||||
commit_log = CommitLog.create(user: user, project: project, repository_id: repository_id,
|
commit_log = CommitLog.create(user: user, project: project, repository_id: repository_id,
|
||||||
name: repository_name, full_name: repository_full_name,
|
name: repository_name, full_name: repository_full_name,
|
||||||
ref: ref, commit_id: commit_id, message: message, created_at: commit_date, updated_at: commit_date)
|
ref: ref, commit_id: commit_id, message: message)
|
||||||
commit_log.project_trends.create(user_id: user.id, project_id: project&.id, action_type: "create") if user.id !=2
|
commit_log.project_trends.create(user_id: user.id, project_id: project&.id, action_type: "create") if user.id !=2
|
||||||
# 统计数据新增
|
# 统计数据新增
|
||||||
CacheAsyncSetJob.perform_later("project_common_service", {commits: 1}, project.id)
|
CacheAsyncSetJob.perform_later("project_common_service", {commits: 1}, project.id)
|
||||||
|
|
||||||
commit_user = User.find_by(mail: commit[:committer][:email]) rescue nil
|
|
||||||
commit_user = User.find_by(login: commit[:committer][:name]) if commit_user.blank? rescue nil
|
|
||||||
next if commit_user.blank?
|
|
||||||
|
|
||||||
# 触发变更issue状态的job
|
|
||||||
close_issue_content = message.to_s.scan(/\b(Close|Closes|Closed|Closing|close|closes|closed|closing)\s*(#\d+(,\s*#\d+)*)?\b/)
|
|
||||||
ChangeIssueStatusByMessageJob.perform_later(commit_id, project, commit_user, close_issue_content[0][1], 5) if close_issue_content[0].present? && close_issue_content[0][1].present?
|
|
||||||
solve_issue_content = message.to_s.scan(/\b(Fix|Fixes|Fixed|Fixing|fix|fixes|fixed|fixing|Resolve|Resolves|Resolved|Resolving|resolve|resolves|resolved|resolving|Implement|Implements|Implemented|Implementing|implement|implements|implemented|implementing)\s*(#\d+(,\s*#\d+)*)?\b/)
|
|
||||||
ChangeIssueStatusByMessageJob.perform_later(commit_id, project, commit_user, solve_issue_content[0][1], 3) if solve_issue_content[0].present? && solve_issue_content[0][1].present?
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -18,7 +18,6 @@ class CompareController < ApplicationController
|
||||||
@page_limit = page_limit <=0 ? 15 : page_limit
|
@page_limit = page_limit <=0 ? 15 : page_limit
|
||||||
@page_offset = (@page_size -1) * @page_limit
|
@page_offset = (@page_size -1) * @page_limit
|
||||||
Rails.logger.info("+========#{@page_size}-#{@page_limit}-#{@page_offset}")
|
Rails.logger.info("+========#{@page_size}-#{@page_limit}-#{@page_offset}")
|
||||||
Rails.logger.info @compare_result
|
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
@ -37,7 +36,7 @@ class CompareController < ApplicationController
|
||||||
if @exist_pullrequest.present?
|
if @exist_pullrequest.present?
|
||||||
return -2, "在这些分支之间的合并请求已存在:<a href='/#{@owner.login}/#{@project.identifier}/pulls/#{@exist_pullrequest.id}'>#{@exist_pullrequest.try(:title)}</a>"
|
return -2, "在这些分支之间的合并请求已存在:<a href='/#{@owner.login}/#{@project.identifier}/pulls/#{@exist_pullrequest.id}'>#{@exist_pullrequest.try(:title)}</a>"
|
||||||
else
|
else
|
||||||
if @compare_result["FilesCount"].to_i == 0 && @compare_result["CommitsCount"].to_i == 0
|
if @compare_result["Commits"].blank? && @compare_result["Diff"].blank?
|
||||||
return -2, "分支内容相同,无需创建合并请求"
|
return -2, "分支内容相同,无需创建合并请求"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue