Compare commits

..

No commits in common. "master" and "pm_project_develop" have entirely different histories.

222 changed files with 1052 additions and 100943 deletions

View File

@ -1,17 +1,13 @@
FROM ubuntu:20.04
RUN apt-get update
RUN DEBIAN_FRONTEND=noninteractive apt install -y tzdata
# basics
RUN apt-get install -y libssl-dev curl libmysqlclient-dev imagemagick nodejs mysql-server redis-server
RUN apt-get install -y libssl-dev curl libmysqlclient-dev imagemagick nodejs mysql-server redis-server tzdata
RUN ln -fs /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
# confirm openssl version
RUN openssl version
RUN which openssl
# install RVM, Ruby, and Bundler
RUN \curl -L https://get.rvm.io | bash -s stable
# rvm environment variable
RUN /bin/bash -l -c "source /etc/profile.d/rvm.sh"
RUN /bin/bash -l -c "rvm requirements"
# replace ruby mirror url, accelerate install ruby
RUN sed -i 's/rvm_remote_server_url2/#rvm_remote_server_url2/g' /usr/local/rvm/config/db
@ -41,19 +37,11 @@ RUN /bin/bash -l -c 'gem install puma -v 5.6.5'
RUN rm -rf Gemfile.lock
RUN cp config/configuration.yml.example config/configuration.yml
RUN cp config/database-docker.yml.example config/database.yml
RUN cp config/database.yml.example config/database.yml
RUN touch config/redis.yml
RUN touch config/elasticsearch.yml
RUN /bin/bash -l -c 'bundle install'
RUN redis-server &
RUN /bin/bash -l -c 'bundle exec rake sync_table_structure:import_csv'
RUN /bin/bash -l -c 'rails db:migrate RAILS_ENV=development'
RUN /bin/bash -l -c 'bundle exec sidekiq -C config/sidekiq.yml -e production -d'
EXPOSE 4000
RUN /bin/bash -l -c 'RAILS_ENV=production puma -C config/puma.rb'
#EXPOSE 4000
#RUN /bin/bash -l -c 'RAILS_ENV=production puma'

View File

@ -1,19 +0,0 @@
FROM ubuntu:20.04
RUN apt-get update
# basics
RUN apt-get install -y libssl-dev curl libmysqlclient-dev imagemagick nodejs mysql-server redis-server tzdata
RUN ln -fs /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
# confirm openssl version
RUN openssl version
RUN which openssl
# install RVM, Ruby, and Bundler
RUN \curl -L https://get.rvm.io | bash -s stable
RUN /bin/bash -l -c "rvm requirements"
# replace ruby mirror url, accelerate install ruby
RUN sed -i 's/rvm_remote_server_url2/#rvm_remote_server_url2/g' /usr/local/rvm/config/db
RUN sed -i 's/cache.ruby-lang.org/cache.ruby-china.com/g' /usr/local/rvm/config/db
# install ruby
RUN /bin/bash -l -c "rvm install 2.4.5"
# confirm ruby version
RUN /bin/bash -l -c "rvm list"
RUN /bin/bash -l -c "ruby -v"

View File

@ -1,6 +1,5 @@
#source 'https://gems.ruby-china.com'
source 'https://mirrors.cloud.tencent.com/rubygems/'
#source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
gem 'rails', '~> 5.2.0'
@ -142,6 +141,6 @@ gem 'doorkeeper'
gem 'doorkeeper-jwt'
gem 'gitea-client', '~> 1.6.1'
gem 'gitea-client', '~> 1.5.8'
gem 'loofah', '~> 2.20.0'

View File

@ -1,3 +1,11 @@
GIT
remote: https://gitlink.org.cn/KingChan/sonarqube.git
revision: 80f07d427322ef02c0714c77a382e87aed0bef81
specs:
sonarqube (1.3.0)
httparty (~> 0.14, >= 0.14.0)
terminal-table (~> 1.5, >= 1.5.1)
GEM
remote: https://mirrors.cloud.tencent.com/rubygems/
specs:
@ -99,7 +107,6 @@ GEM
archive-zip (~> 0.10)
nokogiri (~> 1.8)
chunky_png (1.3.11)
coderay (1.1.3)
concurrent-ruby (1.1.6)
connection_pool (2.2.2)
crass (1.0.6)
@ -136,7 +143,7 @@ GEM
fugit (1.4.1)
et-orbi (~> 1.1, >= 1.1.8)
raabro (~> 1.4)
gitea-client (1.5.9)
gitea-client (1.4.6)
rest-client (~> 2.1.0)
globalid (0.4.2)
activesupport (>= 4.2.0)
@ -149,8 +156,11 @@ GEM
hashie (3.6.0)
htmlentities (4.3.4)
http-accept (1.7.0)
http-cookie (1.0.8)
http-cookie (1.0.5)
domain_name (~> 0.5)
httparty (0.21.0)
mini_mime (>= 1.0.0)
multi_xml (>= 0.5.2)
i18n (1.8.2)
concurrent-ruby (~> 1.0)
io-like (0.3.1)
@ -179,8 +189,7 @@ GEM
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
ruby_dep (~> 1.2)
logger (1.6.6)
loofah (2.20.0)
loofah (2.4.0)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
mail (2.7.1)
@ -189,10 +198,9 @@ GEM
mimemagic (~> 0.3.2)
maruku (0.7.3)
method_source (0.9.2)
mime-types (3.6.0)
logger
mime-types (3.5.2)
mime-types-data (~> 3.2015)
mime-types-data (3.2025.0220)
mime-types-data (3.2024.0507)
mimemagic (0.3.10)
nokogiri (~> 1)
rake
@ -247,13 +255,8 @@ GEM
popper_js (1.16.0)
powerpack (0.1.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)
puma (5.6.5)
puma (5.6.8)
nio4r (~> 2.0)
raabro (1.4.0)
rack (2.0.9)
@ -445,6 +448,8 @@ GEM
actionpack (>= 4.0)
activesupport (>= 4.0)
sprockets (>= 3.0.0)
terminal-table (1.8.0)
unicode-display_width (~> 1.1, >= 1.1.1)
thor (1.0.1)
thread_safe (0.3.6)
tilt (2.0.10)
@ -455,7 +460,9 @@ GEM
thread_safe (~> 0.1)
uglifier (4.2.0)
execjs (>= 0.3.0, < 3)
unf (0.2.0)
unf (0.1.4)
unf_ext
unf_ext (0.0.9.1)
unicode-display_width (1.6.1)
web-console (3.7.0)
actionview (>= 5.0)
@ -497,7 +504,7 @@ DEPENDENCIES
enumerize
faraday (~> 0.15.4)
font-awesome-sass (= 4.7.0)
gitea-client (~> 1.5.8)
gitea-client (~> 1.4.3)
grape-entity (~> 0.7.1)
groupdate (~> 4.1.0)
harmonious_dictionary (~> 0.0.1)
@ -507,7 +514,6 @@ DEPENDENCIES
kaminari (~> 1.1, >= 1.1.1)
letter_avatar
listen (>= 3.0.5, < 3.2)
loofah (~> 2.20.0)
mysql2 (>= 0.4.4, < 0.6.0)
oauth2
omniauth (~> 1.9.0)
@ -520,7 +526,6 @@ DEPENDENCIES
parallel (~> 1.19, >= 1.19.1)
pdfkit
prettier
pry-rails
puma (~> 5.6.5)
rack-cors
rails (~> 5.2.0)
@ -547,6 +552,7 @@ DEPENDENCIES
simple_xlsx_reader (~> 1.0.4)
sinatra
solargraph (~> 0.38.0)
sonarqube!
spreadsheet
spring
spring-watcher-listen (~> 2.0.0)

View File

@ -1,10 +1,9 @@
# GitLink - CCF开源创新服务平台
# GitLink - CCF开源创新服务平台
GitLink确实开源是中国计算机学会CCF官方指定的开源创新服务平台旨在以“为开源创新服务”为使命以“成为开源创新的汇聚地”为愿景秉承“创新、开放、协作、共享”的价值观致力于为大规模开源开放协同创新助力赋能打造创新成果孵化和新工科人才培养的开源创新生态
<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>
<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>
<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>
<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>
<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>
<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>

View File

@ -1,7 +1,6 @@
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 AesCryptHelper
#skip_before_action :check_account, :only => [:logout]
@ -32,12 +31,11 @@ class AccountsController < ApplicationController
username = params[:username]&.gsub(/\s+/, "")
tip_exception("无法使用以下关键词:#{username},请重新命名") if ReversedKeyword.check_exists?(username)
email = params[:email]&.gsub(/\s+/, "")
phone = params[:phone]&.gsub(/\s+/, "")
password = params[:password]
platform = (params[:platform] || 'forge')&.gsub(/\s+/, "")
ActiveRecord::Base.transaction do
result = autologin_register(username, email, password, platform, phone)
result = autologin_register(username, email, password, platform)
if result[:message].blank?
render_ok({user: result[:user]})
else
@ -145,8 +143,7 @@ class AccountsController < ApplicationController
user = Users::RegisterService.call(register_params)
user.mail = "#{user.login}@example.org" if user.mail.blank?
password = decrypt(register_params[:password]) rescue register_params[:password].to_s
password = password.strip
password = register_params[:password].strip
# gitea用户注册, email, username, password
interactor = Gitea::RegisterInteractor.call({username: user.login, email: user.mail, password: password})
@ -196,9 +193,8 @@ class AccountsController < ApplicationController
# 用户登录
def login
password = decrypt(login_params[:password]) rescue login_params[:password].to_s
Users::LoginForm.new(login_params.merge!({password: password})).validate!
@user = User.try_to_login(params[:login], password)
Users::LoginForm.new(login_params).validate!
@user = User.try_to_login(params[:login], params[:password])
return normal_status(-2, "错误的账号或密码") if @user.blank?
# user is already in local database
@ -207,7 +203,7 @@ class AccountsController < ApplicationController
login_control = LimitForbidControl::UserLogin.new(@user)
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
if login_control.remain_times-1 == 0
normal_status(-2, "登录密码出错已达上限,账号已被锁定,请#{login_control.forbid_expires/60}分钟后重新登录或找回密码")
@ -220,24 +216,20 @@ class AccountsController < ApplicationController
LimitForbidControl::UserLogin.new(@user).clear
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
end
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
return render_error("两次输入的密码不一致") if params[:password].to_s != params[:new_password_repeat].to_s
@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.blank?
return render_error("旧密码不正确") unless @user.check_password?(old_password)
return render_error("旧密码不正确") unless @user.check_password?(params[:old_password])
sync_params = {
password: password.to_s,
password: params[:password].to_s,
email: @user.mail,
login_name: @user.name,
source_id: 0
@ -245,7 +237,7 @@ class AccountsController < ApplicationController
interactor = Gitea::User::UpdateInteractor.call(@user.login, sync_params)
if interactor.success?
@user.update_attribute(:password, password)
@user.update_attribute(:password, params[:password])
render_ok
else
render_error(interactor.error)

View File

@ -6,7 +6,7 @@ class Action::NodeInputsController < ApplicationController
@node_inputs = @node.action_node_inputs
respond_to do |format|
format.html
format.json{ render_ok(data: @node_inputs.as_json) }
format.json
end
end
@ -67,9 +67,9 @@ class Action::NodeInputsController < ApplicationController
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)
params.require(:action_node_input).permit(:name, :input_type, :description, :is_required, :sort_no)
else
params.permit(:name, :input_type, :description, :is_required, :sort_no, :default_value)
params.permit(:name, :input_type, :description, :is_required, :sort_no)
end
end
end

View File

@ -4,10 +4,6 @@ class Action::NodeTypesController < ApplicationController
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
@ -24,10 +20,7 @@ class Action::NodeTypesController < ApplicationController
end
def show
respond_to do |format|
format.html
format.json { render_ok(data: @node_type.as_json) }
end
end
def new
@ -52,10 +45,7 @@ class Action::NodeTypesController < ApplicationController
else
flash[:danger] = '删除失败'
end
respond_to do |format|
format.html { redirect_to action_node_types_path }
format.json { render_ok }
end
redirect_to action_node_types_path
end
private

View File

@ -1,25 +1,18 @@
class Action::NodesController < ApplicationController
# before_action :require_admin, except: [:index]
before_action :require_login
before_action :require_admin, except: [:index]
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.html { @nodes = Action::Node.all }
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: '创建成功.' }
@ -40,16 +33,10 @@ class Action::NodesController < ApplicationController
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: '更新成功.' }
@ -63,10 +50,7 @@ class Action::NodesController < ApplicationController
else
flash[:danger] = '删除失败'
end
respond_to do |format|
format.html { redirect_to action_nodes_path }
format.json { render_ok() }
end
redirect_to action_nodes_path
end
private
@ -77,11 +61,9 @@ class Action::NodesController < ApplicationController
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)
params.require(:action_node).permit(:name, :label, :full_name, :description, :icon, :action_node_types_id, :is_local, :local_url, :yaml, :sort_no)
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)
params.permit(:name, :label, :full_name, :description, :icon, :action_node_types_id, :is_local, :local_url, :yaml, :sort_no)
end
end
end

View File

@ -49,10 +49,7 @@ class Action::TemplatesController < ApplicationController
else
flash[:danger] = '删除失败'
end
respond_to do |format|
format.html { redirect_to action_templates_path }
format.json { render_ok }
end
redirect_to action_templates_path
end
private

View File

@ -1,13 +1,9 @@
class Admins::DashboardsController < Admins::BaseController
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
weekly_user_ids = CommitLog.where(created_at: current_week).where("id>= ?", week_greater_id).distinct.pluck(:user_id)
month_user_ids = CommitLog.where(created_at: current_month).where("id>= ?", month_greater_id).distinct.pluck(:user_id)
weekly_user_ids = CommitLog.where(created_at: current_week).pluck(:user_id).uniq
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
@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
@ -22,8 +18,8 @@ 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
weekly_project_ids = (CommitLog.where(created_at: current_week).where("id>= ?", week_greater_id).distinct.pluck(:project_id) + Issue.where(created_on: current_week).pluck(:project_id).uniq).uniq
month_project_ids = (CommitLog.where(created_at: current_month).where("id>= ?", month_greater_id).distinct.pluck(:project_id) + Issue.where(created_on: current_month).pluck(:project_id).uniq).uniq
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).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
@weekly_active_project_count = Rails.cache.fetch("dashboardscontroller:weekly_active_project_count", expires_in: 10.minutes) do
Project.where(updated_on: current_week).or(Project.where(id: weekly_project_ids)).count

View File

@ -2,7 +2,7 @@ class Admins::NpsController < Admins::BaseController
before_action :require_business
def index
@on_off_switch = EduSetting.get("nps-on-off-switch").to_s == 'true'
@user_nps = UserNp.order(created_at: :desc)
@user_nps = UserNp.joins(:user).order(created_at: :desc)
keyword = params[:keyword].to_s.strip.presence
if keyword
sql = 'CONCAT(users.lastname, users.firstname) LIKE :keyword OR users.nickname LIKE :keyword OR users.login LIKE :keyword OR users.mail LIKE :keyword OR users.phone LIKE :keyword'

View File

@ -6,7 +6,7 @@ class Admins::ProjectsController < Admins::BaseController
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'
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 ? OR identifier LIKE ?", "%#{search}%", "%#{search}%").order("#{sort_by} #{sort_direction}")
case params[:category]
when 'public'
projects = projects.where(is_public: true)

View File

@ -37,22 +37,19 @@ class Admins::ProjectsRankController < Admins::BaseController
def export_excel(data)
book = Spreadsheet::Workbook.new
sheet = book.create_worksheet :name => "项目活跃度排行"
sheet.row(0).concat %w(排名 项目全称 项目地址 项目分类 首次创建时间 外部迁移/独立创建 得分 访问数 关注数 点赞数 fork数 疑修数 合并请求数 提交数)
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
sheet[index+1,3] = d.score
sheet[index+1,4] = d.visits
sheet[index+1,5] = d.watchers
sheet[index+1,6] = d.praises
sheet[index+1,7] = d.forks
sheet[index+1,8] = d.issues
sheet[index+1,9] = d.pullrequests
sheet[index+1,10] = d.commits
end
book.write "#{Rails.root}/public/项目活跃度排行.xls"
end

View File

@ -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

View File

@ -27,30 +27,10 @@ class Admins::UsersController < Admins::BaseController
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)
# org_ids = TeamUser.where(user_id: @user.id).pluck(:organization_id) | OrganizationUser.where(user_id: @user.id).pluck(:organization_id)
# organizations = Organization.where(id: org_ids)
# 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)
if @result_object
render_delete_success
else
render_js_error('删除失败!')
end
@user.destroy!
Gitea::User::DeleteService.call(@user.login)
render_delete_success
end
def lock

View File

@ -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

View File

@ -30,8 +30,8 @@ class Api::Pm::BaseController < ApplicationController
end
def load_issue
# return render_parameter_missing if params[:pm_project_id].blank?
@issue = Issue.issue_issue.find_by_id(params[:issue_id])
return render_parameter_missing if params[:pm_project_id].blank?
@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
# 具有对仓库的管理权限

View File

@ -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

View File

@ -145,7 +145,7 @@ class Api::Pm::IssuesController < Api::Pm::BaseController
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]}")
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]
@ -237,65 +237,18 @@ class Api::Pm::IssuesController < Api::Pm::BaseController
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])
return render_parameter_missing if params[:pm_project_id].blank?
@issue = Issue.issue_issue.where(pm_project_id: params[:pm_project_id]).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|
@ -322,7 +275,7 @@ class Api::Pm::IssuesController < Api::Pm::BaseController
: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
:status_ids, :ids, :exclude_ids, :pm_issue_types, :participator_id
)
end
@ -334,7 +287,6 @@ class Api::Pm::IssuesController < Api::Pm::BaseController
: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: [],

View File

@ -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

View File

@ -56,15 +56,12 @@ class Api::Pm::ProjectsController < Api::Pm::BaseController
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
@ -74,9 +71,9 @@ class Api::Pm::ProjectsController < Api::Pm::BaseController
}
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,
"1": type_status_data[1][1].to_i + type_status_data[1][2].to_i,
"2": type_status_data[2][1].to_i + type_status_data[2][2].to_i,
"3": type_status_data[3][1].to_i + type_status_data[3][2].to_i,
}
if type_count_data.keys.size < 3
nedd_add = [1,2,3] - type_count_data.keys
@ -84,24 +81,17 @@ class Api::Pm::ProjectsController < Api::Pm::BaseController
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,
open_data: open_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
time_line = (Time.current.beginning_of_day - 6.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
@ -110,7 +100,7 @@ class Api::Pm::ProjectsController < Api::Pm::BaseController
create_issues: {},
due_issues: {}
}
30.times do |time|
7.times do |time|
current_time = Date.current - time.day
if @create_issues_count.present?
data[:create_issues][current_time] = {

View File

@ -17,8 +17,7 @@ class Api::Pm::SprintIssuesController < Api::Pm::BaseController
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)
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
@ -71,7 +70,7 @@ class Api::Pm::SprintIssuesController < Api::Pm::BaseController
begin
case complete_params[:complete_type].to_i
when 1
@issues.update_all(status_id: 5, due_date: Time.now)
@issues.update_all(status_id: 5)
when 2
@issues.update_all(pm_sprint_id: 0)
when 3

View File

@ -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

View File

@ -46,7 +46,7 @@ class Api::V1::Issues::JournalsController < Api::V1::BaseController
end
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

View File

@ -1,6 +1,6 @@
class Api::V1::IssuesController < Api::V1::BaseController
before_action :require_login, except: [:index, :show, :show_by_id]
before_action :require_public_and_member_above, only: [:index, :show, :show_by_id, :create, :update, :destroy]
before_action :require_public_and_member_above, only: [:index, :show, :show_by_id, :create, :update, :destroy]
before_action :require_operate_above, only: [:batch_update, :batch_destroy]
def index
@ -24,7 +24,7 @@ class Api::V1::IssuesController < Api::V1::BaseController
before_action :check_issue_operate_permission, only: [:update, :destroy]
before_action :load_issue_by_id, only: [:show_by_id]
def 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
@ -70,15 +70,15 @@ class Api::V1::IssuesController < Api::V1::BaseController
private
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
def load_issue_by_id
@issue = Issue.find_by_id(params[:index])
if @issue.blank?
if @issue.blank?
render_not_found("疑修不存在!")
end
end

View File

@ -1,67 +1,5 @@
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)

View File

@ -1,12 +1,8 @@
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
def index
@result_object = Api::V1::Projects::Actions::Runs::ListService.call(@project, {workflow: params[:workflow], page: page, limit: limit}, current_user&.gitea_token)
puts @result_object
end
def create

View File

@ -36,13 +36,11 @@ class Api::V1::Projects::BranchesController < Api::V1::BaseController
def create
@result_object = Api::V1::Projects::Branches::CreateService.call(@project, branch_params, current_user&.gitea_token)
@project.update_column(:updated_on, Time.now)
end
def destroy
@result_object = Api::V1::Projects::Branches::DeleteService.call(@project, params[:name], current_user&.gitea_token)
if @result_object
@project.update_column(:updated_on, Time.now)
# 有开启的pr需要一同关闭
# 1、删除本仓库中存在未关闭的pr,即本仓库分支1->分支2
# 2、如果是fork仓库考虑删除主仓库中存在未关闭的pr,即本仓库分支1->主分支2同时分两种删除1删除本仓库分支12删除主仓库分支2
@ -61,7 +59,6 @@ class Api::V1::Projects::BranchesController < Api::V1::BaseController
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('恢复分支失败!')
@ -73,7 +70,6 @@ class Api::V1::Projects::BranchesController < Api::V1::BaseController
def update_default_branch
@result_object = Api::V1::Projects::Branches::UpdateDefaultBranchService.call(@project, params[:name], current_user&.gitea_token)
if @result_object
@project.update_column(:updated_on, Time.now)
return render_ok
else
return render_error('更新默认分支失败!')

View File

@ -1,5 +1,5 @@
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, :recent]
def index
@result_object = Api::V1::Projects::Commits::ListService.call(@project, {page: page, limit: limit, sha: params[:sha]}, current_user&.gitea_token)
@ -10,14 +10,6 @@ class Api::V1::Projects::CommitsController < Api::V1::BaseController
@result_object = Api::V1::Projects::Commits::DiffService.call(@project, params[:sha], current_user&.gitea_token)
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]

View File

@ -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

View File

@ -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

View File

@ -2,203 +2,51 @@ 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")
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_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)
pullrequest_count = PullRequest.where(project_id: @project.id).count
issue_count = Issue.issue_issue.where(project_id: @project.id).count
commit_count = CommitLog.joins(:project).merge(Project.common).where(project_id: @project.id).count
project_maturity_pullrequest = platform_statistic['max-pullrequest-count'].to_i == 0 ? 0 : 30*(pullrequest_count.to_f/platform_statistic['max-pullrequest-count'].to_i)
project_maturity_issue = platform_statistic['max-issue-count'].to_i == 0 ? 0 : 30*(issue_count.to_f/platform_statistic['max-issue-count'].to_i)
project_maturity_commit = platform_statistic['max-commit-count'].to_i == 0 ? 0 : 40*(commit_count.to_f/platform_statistic['max-commit-count'].to_i)
project_maturity = format("%.2f", project_maturity_pullrequest + project_maturity_issue + project_maturity_commit)
# 项目健康度
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
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
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)
project_health_issue = (issue_count < 10 || closed_issue_count < 10) ? 0 : 40*(closed_issue_count-10).to_f/(issue_count-10)
project_health_pullrequest = (pullrequest_count < 5 || closed_pullrequest_count < 5) ? 0 : 30*(closed_pullrequest_count-5).to_f/(pullrequest_count-5)
project_health_license = 20*has_license
project_health = format("%.2f", project_health_issue + project_health_pullrequest + project_health_license)
# 团队影响度
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)
member_count = Member.where(project_id: @project.id).count
recent_one_month_member_count = Member.where(project_id:@project.id).where("created_on > ?", Time.now - 30.days).count
team_impact_member = platform_statistic['max-member-count'].to_i == 0 ? 0 : 40*(member_count.to_f/platform_statistic['max-member-count'].to_i)
team_impact_recent_member = platform_statistic['max-recent-one-month-member-count'].to_i == 0 ? 0 : 60*(recent_one_month_member_count.to_f/platform_statistic['max-recent-one-month-member-count'].to_i)
team_impact = format("%.2f", team_impact_member + team_impact_recent_member)
# 开发活跃度
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)
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_commit_count = CommitLog.joins(:project).merge(Project.common).where(project_id: @project.id).where("created_at > ?", Time.now - 30.days).count
develop_activity_pullrequest = platform_statistic['max-recent-one-month-pullrequest-count'].to_i == 0 ? 0 : 20*(recent_one_month_pullrequest_count.to_f/platform_statistic['max-recent-one-month-pullrequest-count'].to_i)
develop_activity_issue = platform_statistic['max-recent-one-month-issue-count'].to_i == 0 ? 0 : 20*(recent_one_month_issue_count.to_f/platform_statistic['max-recent-one-month-issue-count'].to_i)
develop_activity_commit = platform_statistic['max-recent-one-month-commit-count'].to_i == 0 ? 0 : 40*(recent_one_month_commit_count.to_f/platform_statistic['max-recent-one-month-commit-count'].to_i)
develop_activity = format("%.2f", 20 + develop_activity_pullrequest + develop_activity_issue + develop_activity_commit)
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

View File

@ -6,21 +6,13 @@ class Api::V1::Projects::Pulls::PullsController < Api::V1::BaseController
@pulls = kaminari_paginate(@pulls)
end
before_action :load_pull_request, only: [:show, :files]
before_action :load_pull_request, only: [:show]
def show
@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
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
def query_params
params.permit(:status, :keyword, :priority_id, :issue_tag_id, :version_id, :reviewer_id, :sort_by, :sort_direction)

View File

@ -1,8 +1,5 @@
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)
@ -20,7 +17,6 @@ class Api::V1::SonarqubesController < Api::V1::BaseController
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')
@ -31,9 +27,7 @@ class Api::V1::SonarqubesController < Api::V1::BaseController
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?
@ -67,9 +61,6 @@ class Api::V1::SonarqubesController < Api::V1::BaseController
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:
@ -92,13 +83,11 @@ class Api::V1::SonarqubesController < Api::V1::BaseController
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,
"content": "sonar.projectKey=#{params[:owner]}-#{@project.id}\nsonar.sources=.\nsonar.java.binaries=.",
"message": 'Add sonar-project.properties',
committer: {
email: @owner.mail,
@ -106,7 +95,6 @@ class Api::V1::SonarqubesController < Api::V1::BaseController
},
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']))
@ -160,31 +148,6 @@ class Api::V1::SonarqubesController < Api::V1::BaseController
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],

View File

@ -8,6 +8,6 @@ class Api::V1::Users::ProjectsController < Api::V1::BaseController
private
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

View File

@ -1,5 +1,4 @@
class Api::V1::UsersController < Api::V1::BaseController
include AesCryptHelper
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]
@ -54,7 +53,7 @@ class Api::V1::UsersController < Api::V1::BaseController
end
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, "密码错误") unless @observe_user.check_password?(password)
render_ok
@ -116,29 +115,4 @@ class Api::V1::UsersController < Api::V1::BaseController
return render_error('更改手机号失败!')
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

View File

@ -210,10 +210,6 @@ class ApplicationController < ActionController::Base
tip_exception(401, "请登录后再操作") unless User.current.logged?
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
if params[:token].present?
user = User.try_to_autologin(params[:token])
@ -360,7 +356,7 @@ class ApplicationController < ActionController::Base
User.current = User.find 8686
elsif params[:debug] == 'admin'
logger.info "@@@@@@@@@@@@@@@@@@@@@@ debug mode....."
user = User.find 36480
user = User.find 1
User.current = user
cookies.signed[:user_id] = user.id
end
@ -380,7 +376,7 @@ class ApplicationController < ActionController::Base
# 多浏览器退出账号时token不存在处理
if current_domain_session && autologin_user.nil?
autologin_user = (User.active.find(current_domain_session) rescue nil)
set_autologin_cookie(autologin_user) if autologin_user.present?
set_autologin_cookie(autologin_user)
end
autologin_user
end
@ -421,6 +417,24 @@ class ApplicationController < ActionController::Base
"#{edu_setting('git_address_domain')}/#{repo_path}"
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请求
def uri_post(uri, params)
begin
@ -512,6 +526,112 @@ class ApplicationController < ActionController::Base
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="...")
ss = ""
if !text.nil? && text.length>0
@ -1052,46 +1172,15 @@ class ApplicationController < ActionController::Base
# 接口限流,请求量大有性能问题
def request_limit
white_list_ip = ["106.75.110.152"]
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')}}")
record_count = Rails.cache.read("request/#{controller_name}/#{Time.now.strftime('%Y%m%d%H%M')}/#{request.remote_ip}")
if record_count.present?
record_count = record_count + 1
else
record_count = 1
end
Rails.logger.info("请求太快,请稍后再试。#{request.path}") if record_count > 1000
tip_exception("请求太快,请稍后再试。") if record_count > 1000
tip_exception("请求太快,请稍后再试。") if record_count > 100
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

View File

@ -30,33 +30,25 @@ class AttachmentsController < ApplicationController
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?
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")
domain = GiteaService.gitea_config[:domain]
api_url = GiteaService.gitea_config[:base_url]
url = ("/repos"+url.split(base_url + "/api")[1])
filepath, ref = url.split("/")[-1].split("?")
url.gsub!(url.split("/")[-1], '')
# Rails.logger.info("url===#{url}")
Rails.logger.info("url===#{url}")
Rails.logger.info(filepath)
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
request_url = [domain, api_url, URI.encode(url), URI.escape(filepath), "?ref=#{URI.escape(ref.split('ref=')[1])}&access_token=#{User.where(admin: true).take&.gitea_token}"].join
Rails.logger.info("request_url===#{request_url}")
File.delete(tmp_path) if File.exist?(tmp_path) # 删除之前的文件
Util.download_file(request_url, tmp_path)
response = Faraday.get(request_url)
filename = filepath
else
File.delete(tmp_path) if File.exist?(tmp_path) # 删除之前的文件
Util.download_file(URI.encode(url), tmp_path)
response = Faraday.get(URI.encode(url))
filename = params[:download_url].to_s.split("/").pop()
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
def create

View File

@ -19,23 +19,12 @@ class CommitLogsController < ApplicationController
params[:commits].each do |commit|
commit_id = commit[:id]
message = commit[:message]
commit_date = Time.parse(commit[:timestamp]) || Time.now
commit_log = CommitLog.create(user: user, project: project, repository_id: repository_id,
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
# 统计数据新增
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

View File

@ -18,7 +18,6 @@ class CompareController < ApplicationController
@page_limit = page_limit <=0 ? 15 : page_limit
@page_offset = (@page_size -1) * @page_limit
Rails.logger.info("+========#{@page_size}-#{@page_limit}-#{@page_offset}")
Rails.logger.info @compare_result
end
private
@ -37,7 +36,7 @@ class CompareController < ApplicationController
if @exist_pullrequest.present?
return -2, "在这些分支之间的合并请求已存在:<a href='/#{@owner.login}/#{@project.identifier}/pulls/#{@exist_pullrequest.id}'>#{@exist_pullrequest.try(:title)}</a>"
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, "分支内容相同,无需创建合并请求"
end
end

View File

@ -3,7 +3,7 @@ module Api::PullHelper
def load_pull_request
pull_request_id = params[:pull_id] || params[:id]
@pull_request = @project.pull_requests.where(gitea_number: pull_request_id).where.not(id: pull_request_id).take || @project.pull_requests.find_by_id(pull_request_id)
@pull_request = @project.pull_requests.where(gitea_number: pull_request_id).where.not(id: pull_request_id).take || PullRequest.find_by_id(pull_request_id)
@issue = @pull_request&.issue
if @pull_request
logger.info "###########pull_request founded"

View File

@ -77,12 +77,4 @@ module GitHelper
cha_path = path.present? ? path.split("") : []
cha_path.reject(&:blank?)[0].try(:strip)
end
def expain_issue_commit(commit_message)
respace_arr= commit_message.to_s.scan(/#(\d+)/).map{|s|[s[0], "##{s[0]}"]}.uniq.sort_by{|s|-s[0].to_i}
respace_arr.each do |item|
issue = Issue.find_by_id(item[0].to_i)
end
end
end

View File

@ -32,8 +32,18 @@ module LaboratoryHelper
end
def default_course_links
# my_projects: "/users/#{current_user.try(:login)}/projects",
# my_projects: "https://www.trustie.net/users/#{current_user.try(:login)}/user_projectlist",
{
default_url: Rails.application.config_for(:configuration)['platform_url']
new_syllabuses: "https://www.trustie.net/syllabuses/new",
new_course: "https://www.trustie.net/courses/new",
edit_account: "https://www.trustie.net/my/account",
my_courses: "https://www.trustie.net/users/#{current_user.try(:login)}/user_courselist",
my_projects: "/users/#{current_user.try(:login)}/projects",
my_organ: "https://www.trustie.net/users/#{current_user.try(:login)}/user_organizations",
default_url: Rails.application.config_for(:configuration)['platform_url'],
tiding_url: "https://www.trustie.net/users/#{current_user.try(:login)}/user_messages",
register_url: "https://www.trustie.net/login?login=false"
}
end
end

View File

@ -73,17 +73,6 @@ module LoginHelper
session[:"#{default_yun_session}"] = nil
end
def clear_user_cookie
if edu_setting('cookie_domain').present?
cookies.delete(autologin_cookie_name, domain: edu_setting('cookie_domain'))
else
cookies.delete(autologin_cookie_name)
end
# 清除前端写入的用户名
Rails.logger.info("########________cookies['login']___________###########{cookies['login']}")
cookies.delete("login")
end
# Sets the logged in user
def logged_user=(user)
reset_session

View File

@ -1,17 +0,0 @@
class HomeController < ApplicationController
def index
@user_count = Rails.cache.fetch("homecontroller:user_count", expires_in: 1.hours) do
User.count
end
@project_count = Rails.cache.fetch("homecontroller:project_count", expires_in: 1.hours) do
Project.count
end
@project_dataset_count = Rails.cache.fetch("homecontroller:project_dataset_count", expires_in: 1.hours) do
ProjectDataset.count
end
@commit_count = Rails.cache.fetch("homecontroller:commit_count", expires_in: 1.hours) do
CommitLog.count
end
end
end

View File

@ -4,8 +4,4 @@ class LicensesController < ApplicationController
q = License.ransack(name_cont: params[:name])
@licenses = q.result(distinct: true)
end
def show
@license = License.find(params[:id])
end
end

View File

@ -21,7 +21,6 @@ class MainController < ApplicationController
end
def index
Rails.logger.info("request.referer============#{request.referer},#{params[:path]}") if request.referer.to_s.include?("educoder.net")
domain_session = params[:_educoder_session]
if domain_session
uid_logger("main start domain_session is #{domain_session}")

View File

@ -50,7 +50,7 @@ class MarkFilesController < ApplicationController
end
def load_pull_request
@pull_request = @project.pull_requests.where(gitea_number: params[:id]).where.not(id: params[:id]).take || @project.pull_requests.find_by_id(params[:id])
@pull_request = @project.pull_requests.where(gitea_number: params[:id]).where.not(id: params[:id]).take || PullRequest.find_by_id(params[:id])
end
end

View File

@ -1,53 +0,0 @@
class Oauth::Ci4sController < Oauth::BaseController
include RegisterHelper
def oauth_url
redirect_to Ci4s::Service.oauth_url
end
# 需要educoder那边设置回调地址
def create
begin
code = params['code'].to_s.strip
tip_exception("code不能为空") if code.blank?
new_user = false
token = Ci4s::Service.access_token(code)
Rails.logger.info("[OAuth2] result -> #{token}")
result = Ci4s::Service.user_info(token[:access_token])
tip_exception("请求用户信息错误") if result['code'].to_i != 200
user_info = result['data']
# 存在该用户
open_user = OpenUsers::Ci4s.find_by(uid: user_info['username'])
if open_user.present? && open_user.user.present?
successful_authentication(open_user.user)
redirect_to root_path(new_user: false)
return
else
if current_user.blank? || !current_user.logged?
new_user = true
session[:unionid] = user_info['username']
# login = User.generate_login('E')
login = user_info['username']
email = user_info['email']
email = "#{login}@forge.com" if email.blank?
reg_result = autologin_register(login, email, "Ec#{login}2021#", 'educoder', user_info['mobile'])
Rails.logger.info("[OAuth2] reg_result -> #{reg_result}")
if reg_result[:message].blank?
open_user = OpenUsers::Ci4s.create!(user_id: reg_result[:user][:id], uid: login, extra: user_info)
successful_authentication(open_user.user)
else
tip_exception(reg_result[:message])
end
else
OpenUsers::Ci4s.create!(user: current_user, uid: user_info['username'], extra: user_info)
end
end
Rails.logger.info("[OAuth2] session[:unionid] -> #{session[:unionid]}")
redirect_to root_path(new_user: new_user)
rescue Exception => ex
render_error(ex.message)
end
end
end

View File

@ -45,9 +45,6 @@ class Oauth::EducoderController < Oauth::BaseController
result = EducoderOauth::Service.access_token(code)
result = EducoderOauth::Service.user_info(result[:access_token])
Rails.logger.info("OAuth2-session-unionid====111=======#{result['login']}")
tip_exception("调用头歌接口错误") if result['login'].blank?
# 存在该用户
open_user = OpenUsers::Educoder.find_by(uid: result['login'])
if open_user.present? && open_user.user.present?
@ -71,7 +68,7 @@ class Oauth::EducoderController < Oauth::BaseController
OpenUsers::Educoder.create!(user: current_user, uid: result['login'], extra: result)
end
end
Rails.logger.info("OAuth2-session-unionid=========== #{session[:unionid]}")
Rails.logger.info("[OAuth2] session[:unionid] -> #{session[:unionid]}")
redirect_to "/bindlogin/educoder"
# redirect_to root_path(new_user: new_user)

View File

@ -1,4 +1,4 @@
class Oauth2Controller < ApplicationController
class Oauth2Controller < ActionController::Base
layout 'doorkeeper/application'
include LoginHelper
@ -6,9 +6,6 @@ class Oauth2Controller < ApplicationController
client_id = params[:call_url].split("client_id=")[1].split("&redirect_uri")[0]
@call_url = request.fullpath.split('call_url=').last
@app = Doorkeeper::Application.find_by(uid: client_id)
if User.current.logged?
redirect_to @call_url + "&auth=" + User.current.login
end
end
def create

View File

@ -1,5 +1,4 @@
class Organizations::OrganizationsController < Organizations::BaseController
include AesCryptHelper
before_action :require_login, except: [:index, :show, :recommend, :languages]
# before_action :require_profile_completed, only: [:create]
before_action :convert_image!, only: [:create, :update]
@ -140,7 +139,7 @@ class Organizations::OrganizationsController < Organizations::BaseController
end
def password
decrypt(params[:password]) rescue params[:password].to_s
params.fetch(:password, "")
end
def load_organization

View File

@ -12,7 +12,7 @@ class Organizations::ProjectsController < Organizations::BaseController
keywords = params[:search].to_s.each_char.select { |c| c.bytes.first < 240 }.join('')
@projects = @projects.where(id: params[:pm_project_repository_ids].split(',')) if params[:pm_project_repository_ids].present?
@projects = @projects.where.not(id: params[:exclude_ids].to_s.split(",")) if params[:exclude_ids].present?
@projects = @projects.where(project_type: ['mirror', 'common']).where("gpid is not null") if params[:actived].present?
@projects = @projects.where("gpid is not null") if params[:actived].present?
@projects = @projects.ransack(name_or_identifier_cont: keywords).result if params[:search].present?
@projects = @projects.includes(:owner).order("projects.#{sort} #{sort_direction}")
@projects = paginate(@projects)

View File

@ -11,10 +11,7 @@ class OwnersController < ApplicationController
end
def show
# login = params[:id].to_s[0..-6]
login = params[:id].to_s
@owner = Owner.find_by(login: login) || Owner.find_by(id: login)
clear_user_cookie unless @owner.present?
@owner = Owner.find_by(login: params[:id]) || Owner.find_by(id: params[:id])
return render_not_found unless @owner.present?
# 组织
if @owner.is_a?(Organization)

View File

@ -253,7 +253,6 @@ class ProjectsController < ApplicationController
def destroy
if current_user.admin? || @project.manager?(current_user)
ActiveRecord::Base.transaction do
UserAction.create(action_id: @project.id, action_type: "DestroyProject", user_id: current_user.id, :ip => request.remote_ip, data_bank: @project.attributes.to_json)
close_fork_pull_requests_by(@project)
Gitea::Repository::DeleteService.new(@project.owner, @project.identifier,current_user.gitea_token).call
@project.destroy!
@ -287,19 +286,13 @@ class ProjectsController < ApplicationController
end
def watch_users
start_at = params[:start_at]
end_at = params[:end_at]
watchers = @project.watchers.includes(:user).order("watchers.created_at desc").distinct
watchers = watchers.where("watchers.created_at > ? and watchers.created_at < ?", Time.at(start_at.to_i), Time.at(end_at.to_i)) if start_at.present? && end_at.present?
@watchers_count = watchers.size
@watchers = paginate(watchers)
end
def praise_users
start_at = params[:start_at]
end_at = params[:end_at]
praises = @project.praise_treads.includes(:user).order("praise_treads.created_at desc").distinct
praises = praises.where("praise_treads.created_at > ? and praise_treads.created_at < ?", Time.at(start_at.to_i), Time.at(end_at.to_i)) if start_at.present? && end_at.present?
@praises_count = praises.size
@praises = paginate(praises)
end
@ -372,7 +365,7 @@ class ProjectsController < ApplicationController
if @project_detail.save!
attachment_ids = Array(params[:attachment_ids])
logger.info "=============> #{Array(params[:attachment_ids])}"
@attachments = Attachment.where(id: attachment_ids).or(Attachment.where(uuid: attachment_ids))
@attachments = Attachment.where(id: attachment_ids)
@attachments.update_all(
container_id: @project_detail.id,
container_type: @project_detail.model_name.name,

View File

@ -253,7 +253,6 @@ class PullRequestsController < ApplicationController
normal_status(-1, result.message)
end
rescue => e
logger_error(e)
normal_status(-1, e.message)
raise ActiveRecord::Rollback
end
@ -296,11 +295,11 @@ class PullRequestsController < ApplicationController
private
def load_pull_request
@pull_request = @project.pull_requests.where(gitea_number: params[:id]).where.not(id: params[:id]).take || @project.pull_requests.find_by_id(params[:id])
@pull_request = @project.pull_requests.where(gitea_number: params[:id]).where.not(id: params[:id]).take || PullRequest.find_by_id(params[:id])
end
def find_pull_request
@pull_request = @project.pull_requests.where(gitea_number: params[:id]).where.not(id: params[:id]).take || @project.pull_requests.find_by_id(params[:id])
@pull_request = @project.pull_requests.where(gitea_number: params[:id]).where.not(id: params[:id]).take || PullRequest.find_by_id(params[:id])
@issue = @pull_request&.issue
if @pull_request.blank?
normal_status(-1, "合并请求不存在")

View File

@ -13,9 +13,6 @@ class RepositoriesController < ApplicationController
before_action :get_ref, only: %i[entries sub_entries top_counts files archive]
before_action :get_latest_commit, only: %i[entries sub_entries top_counts]
before_action :get_statistics, only: %i[top_counts]
before_action :require_referer, only: [:raw]
# before_action :request_limit, only: [:raw]
before_action :request_raw_limit, only: [:raw]
def files
result = @project.educoder? ? nil : Gitea::Repository::Files::GetService.call(@owner, @project.identifier, @ref, params[:search], @owner.gitea_token)
@ -37,10 +34,6 @@ class RepositoriesController < ApplicationController
@fork_project = Project.find_by(id: @project_fork_id)
@fork_project_user = @fork_project.owner
end
# 修正默认分支
if @result[:repo].present? && @result[:repo]['default_branch'].present? && @result[:repo]['default_branch'] != @project.default_branch
@project.update_column('default_branch', @result[:repo]['default_branch'])
end
rescue Exception => e
uid_logger_error(e.message)
tip_exception(e.message)
@ -157,8 +150,8 @@ class RepositoriesController < ApplicationController
return render_error('暂未开放,敬请期待.')
else
@commit = Gitea::Repository::Commits::GetService.call(@owner.login, @repository.identifier, @sha, @owner&.gitea_token)
# @commit_diff = Gitea::Repository::Commits::GetService.call(@owner.login, @repository.identifier, @sha, @owner&.gitea_token, {diff: true})
render_error(@commit[:message], @commit[:status]) if @commit.has_key?(:status)#|| @commit_diff.has_key?(:status)
@commit_diff = Gitea::Repository::Commits::GetService.call(@owner.login, @repository.identifier, @sha, @owner&.gitea_token, {diff: true})
render_error(@commit[:message], @commit[:status]) if @commit.has_key?(:status) || @commit_diff.has_key?(:status)
end
end
@ -304,7 +297,7 @@ class RepositoriesController < ApplicationController
redirect_to file_path
end
def raw
def raw
domain = GiteaService.gitea_config[:domain]
api_url = GiteaService.gitea_config[:base_url]

View File

@ -14,7 +14,7 @@ class ReviewsController < ApplicationController
end
def load_pull_request
@pull_request = @project.pull_requests.where(gitea_number: params[:id]).where.not(id: params[:id]).take || @project.pull_requests.find_by_id(params[:id])
@pull_request = @project.pull_requests.where(gitea_number: params[:id]).where.not(id: params[:id]).take || PullRequest.find_by_id(params[:id])
end
end

View File

@ -1,12 +1,13 @@
class SettingsController < ApplicationController
def show
@old_projects_url = nil
get_navbar
site_page_deploy_domain
get_add_menu
get_common_menu
get_sub_competitions
get_personal_menu
# get_third_party
get_third_party
get_third_party_new
get_top_system_notification
end

View File

@ -54,9 +54,9 @@ class SitePagesController < ApplicationController
user = User.find_by_login params[:repository][:owner][:login]
return normal_status(-1, '你还未开通Page服务无法进行部署') unless user.website_permission
project = Project.find_by(identifier: params[:repository][:name],user_id: user.id)
return normal_status(-1, '项目不存在') if project.nil?
return normal_status(-1, '该仓库还未开通Page服务无法进行部署') unless Page.exists?(user: user, project: project)
project = Project.where(identifier: params[:repository][:name],user_id: user.id)
return normal_status(-1, '你没有权限操作') if project.owner?(user)
return normal_status(-1, '该仓库还未开通Page服务无法进行部署') if Page.exists?(user: user, project: project)
@page = Page.find_by(user: user, project: project)
response_str = @page.deploy_page(branch)

View File

@ -10,8 +10,6 @@ class Users::MessagesController < Users::BaseController
result = Notice::Read::ListService.call(observed_user.id, message_type, message_status, page, limit)
return render_error if result.nil?
@data = result[2]
rescue
render_ok
end
def create

View File

@ -263,7 +263,7 @@ class UsersController < ApplicationController
begin
@user = current_user
begin
result = EduSetting.get("notice_disable").to_s == "true" ? nil : Notice::Read::CountService.call(current_user.id)
result = Notice::Read::CountService.call(current_user.id)
@message_unread_total = result.nil? ? 0 : result[2]["unread_notification"]
rescue
@message_unread_total = 0
@ -714,7 +714,6 @@ class UsersController < ApplicationController
private
def load_user
@user = User.find_by_login(params[:id]) || User.find_by(id: params[:id])
clear_user_cookie unless @user.present?
end
def user_params

View File

@ -168,6 +168,7 @@ class VersionReleasesController < ApplicationController
attachment.container = target
attachment.author_id = current_user.id
attachment.description = ""
attachment.uuid = SecureRandom.uuid
attachment.save
end
end

View File

@ -5,10 +5,7 @@ class WatchersController < ApplicationController
before_action :get_target
def index
start_at = params[:start_at]
end_at = params[:end_at]
scope = @target.watchers.includes(:user)
scope = scope.where("watchers.created_at > ? and watchers.created_at < ?", Time.at(start_at.to_i), Time.at(end_at.to_i)) if start_at.present? && end_at.present?
@watchers = paginate(scope)
end

View File

@ -1,6 +1,5 @@
class BaseForm
include ActiveModel::Model
include AesCryptHelper
Error = Class.new(StandardError)
EmailError = Class.new(Error)
@ -54,15 +53,11 @@ class BaseForm
end
def check_password(password)
password = decrypt(password) rescue password
password = strip(password)
raise PasswordFormatError, "密码8~16位密码支持字母数字和符号" unless password =~ CustomRegexp::PASSWORD
end
def check_password_confirmation(password, password_confirmation)
password = decrypt(password) rescue password
password_confirmation = decrypt(password_confirmation) rescue password_confirmation
password = strip(password)
password_confirmation = strip(password_confirmation)

View File

@ -9,7 +9,7 @@ module Register
login_exist = Owner.exists?(login: login) || ReversedKeyword.check_exists?(login)
if user.present?
raise LoginError, '登录名已被他人使用' if login_exist && login != user&.login
raise LoginError, '登录名已被使用' if login_exist && login != user&.login
else
raise LoginError, '登录名已被使用' if login_exist
end

View File

@ -8,7 +8,7 @@ module Register
def check!
user = User.find_by(id: user_id)
Rails.logger.info "Register::RemoteForm params: id: #{user_id}; username: #{username}; email: #{email}; password: #{password}; platform: #{platform}"
Rails.logger.info "Register::RemoteForm params: id: #{user&.id}; username: #{username}; email: #{email}; password: #{password}; platform: #{platform}"
check_login(username, user)
check_mail(email,user)
check_password(password)

View File

@ -1,45 +0,0 @@
module AesCryptHelper
AES_KEY = EduSetting.get("login_crypt_key") || '59c96c3572ab8cc1'
def encrypt(plain_text, output_encoding = 'base64')
# 将字符串密钥和IV转换为16字节的字节数组
key = AES_KEY.byteslice(0, 16)
iv = AES_KEY.byteslice(0, 16)
# 创建并设置AES-CBC加密器
cipher = OpenSSL::Cipher.new('AES-128-CBC')
cipher.encrypt
cipher.key = key
cipher.iv = iv
# 加密数据并添加PKCS7填充
encrypted_data = cipher.update(plain_text) + cipher.final
# 将加密数据转换为Base64编码
Base64.strict_encode64(encrypted_data)
end
def decrypt(cipher_text, input_encoding = 'base64')
# 确保密钥是16字节长
key = AES_KEY.byteslice(0, 16) # 如果密钥不足16字节填充空格如果超过截断
iv = AES_KEY.byteslice(0, 16)
decipher = OpenSSL::Cipher.new('AES-128-CBC')
decipher.decrypt
decipher.key = key
decipher.iv = iv
# 根据输入编码解码密文
decrypted_data = case input_encoding
when 'base64'
Base64.strict_decode64(cipher_text)
else
cipher_text
end
decrypted = decipher.update(decrypted_data) + decipher.final
decrypted
end
end

View File

@ -146,13 +146,13 @@ module ApplicationHelper
# 用户图像url如果不存在的话source为匿名用户即默认使用匿名用户图像
def url_to_avatar(source)
if File.exist?(disk_filename(source&.class, source&.id))
ctime = File.ctime(disk_filename(source&.class, source&.id)).to_i
if %w(User Organization).include?(source&.class.to_s)
File.join("images", relative_path, ["#{source&.class}", "#{source&.id}"]) + "?t=#{ctime}"
ctime = File.ctime(disk_filename(source.class, source.id)).to_i
if %w(User Organization).include?(source.class.to_s)
File.join("images", relative_path, ["#{source.class}", "#{source.id}"]) + "?t=#{ctime}"
else
File.join("images/avatars", ["#{source&.class}", "#{source&.id}"]) + "?t=#{ctime}"
File.join("images/avatars", ["#{source.class}", "#{source.id}"]) + "?t=#{ctime}"
end
elsif source&.class.to_s == 'User'
elsif source.class.to_s == 'User'
source.get_letter_avatar_url
end
end

View File

@ -13,13 +13,13 @@ module AvatarHelper
def url_to_avatar(source)
if File.exist?(disk_filename(source&.class, source&.id))
ctime = File.ctime(disk_filename(source&.class, source&.id)).to_i
if %w(User Organization).include?(source&.class.to_s)
File.join("images", relative_path, ["#{source&.class}", "#{source&.id}"]) + "?t=#{ctime}"
ctime = File.ctime(disk_filename(source.class, source.id)).to_i
if %w(User Organization).include?(source.class.to_s)
File.join("images", relative_path, ["#{source.class}", "#{source.id}"]) + "?t=#{ctime}"
else
File.join("images/avatars", ["#{source&.class}", "#{source&.id}"]) + "?t=#{ctime}"
File.join("images/avatars", ["#{source.class}", "#{source.id}"]) + "?t=#{ctime}"
end
elsif source&.class.to_s == 'User'
elsif source.class.to_s == 'User'
source.get_letter_avatar_url
end
end

View File

@ -129,7 +129,7 @@ module ProjectsHelper
end
def jianmu_devops_url
EduSetting.get("jianmu_devops_url")
EduSetting.get("jianmu_devops_url") || "https://ci-v3.test.jianmuhub.com"
end
@ -145,18 +145,15 @@ module ProjectsHelper
url = EduSetting.get("ai_shang_url") || "https://shang.gitlink.org.cn"
case project.identifier.to_s.downcase
when nil then ""
# when 'rails' then "#{url}/v1/rails/entropy"
# when 'jittor' then "#{url}/v1/jittor/entropy"
# when 'paddle' then "#{url}/v1/Paddle/entropy"
# when 'vue' then "#{url}/v1/vue/entropy"
# when 'bootstrap' then "#{url}/v1/bootstrap/entropy"
# when 'tensorflow' then "#{url}/v1/tensorflow/entropy"
# when 'kernel' then "#{url}/v1/openeuler/entropy"
# when 'opengauss-server' then "#{url}/v1/opengauss/entropy"
# when 'mindspore' then "#{url}/v1/mindspore/entropy"
when 'openharmony-kernel' then "#{url}/api/openharmony/entropy"
when 'kernel' then "#{url}/api/openeuler/entropy"
when 'xiuos' then "#{url}/api/xiuos/entropy"
when 'rails' then "#{url}/v1/rails/entropy"
when 'jittor' then "#{url}/v1/jittor/entropy"
when 'paddle' then "#{url}/v1/Paddle/entropy"
when 'vue' then "#{url}/v1/vue/entropy"
when 'bootstrap' then "#{url}/v1/bootstrap/entropy"
when 'tensorflow' then "#{url}/v1/tensorflow/entropy"
when 'kernel' then "#{url}/v1/openeuler/entropy"
when 'opengauss-server' then "#{url}/v1/opengauss/entropy"
when 'mindspore' then "#{url}/v1/mindspore/entropy"
else ''
end
end

View File

@ -161,7 +161,6 @@ module RepositoriesHelper
s_content = s_content.starts_with?("/") ? s_content[1..-1] : s_content[0..-1]
s_content = File.expand_path(s_content, file_path)
s_content = s_content.split("#{Rails.root}/")[1]
next if s_content.blank?
# content = content.gsub(s[0], "/#{s_content}")
join_xxx = s_content.include?("?") ? "&" : "?"
s_content = [base_url, "/api/#{owner&.login}/#{repo.identifier}/raw/#{s_content}#{join_xxx}ref=#{ref}"].join
@ -191,7 +190,6 @@ module RepositoriesHelper
path = [owner&.login, repo&.identifier, 'tree', ref, file_path].join("/")
s_content = File.expand_path(s_content, path)
s_content = s_content.split("#{Rails.root}")[1]
next if s_content.blank?
case k.to_s
when 'ss_src'
content = content.gsub("src=\"#{s[0]}\"", "src=\"/#{s_content}\"")
@ -204,7 +202,7 @@ module RepositoriesHelper
when 'ss_href_1'
content = content.gsub("href=\'#{s[0]}\'", "href=\'#{s_content}\'")
else
content = content.gsub("(#{s[0]})", "(#{s_content})")
content = content.gsub("(#{s[0]})", "(/#{s_content})")
end
end
rescue

View File

@ -1,46 +0,0 @@
class ChangeIssueStatusByMessageJob < ApplicationJob
queue_as :notify
# Close, Closes, Closed, Closing, close, closes, closed, closing
# Fix, Fixes, Fixed, Fixing, fix, fixes, fixed, fixing
# Resolve, Resolves, Resolved, Resolving, resolve, resolves, resolved, resolving
# Implement, Implements, Implemented, Implementing, implement, implements, implemented, implementing
# 以上关键词后接 issue_id 例如Closes #234 Closes #123, #245, #992
def get_pm_issue_data(user, org, pm_project_id, issue_id)
url = "#{EduSetting.get("pms_server_url")}/api/pms/#{org.login}/pmsProjectIssues/#{issue_id}?pmProjectId=#{pm_project_id}"
headers = {
'Cookie' => "autologin_trustie=#{Token.get_or_create_permanent_login_token(user, 'autologin')&.value}",
}
response = RestClient.get(url, headers)
puts response.body
return JSON.parse(response.body)["code"].to_i == 200
rescue
return false
end
def perform(commitsha, project, user, tag_issue_id_content, status_id=1)
Rails.logger.info "需要操作的issue_id内容为 #{tag_issue_id_content}"
tag_issue_id_content = tag_issue_id_content.gsub(/\s+/, '')
tag_issue_id_content.to_s.split(",").each do |tag_issue|
issue_id = tag_issue.gsub('#', '')
issue = project.issues.issue_issue.where(project_issues_index: issue_id).where.not(id: issue_id).take || Issue.issue_issue.find_by_id(issue_id)
next unless issue.present? # issue不存在 跳过
next if issue.project.present? && !issue.project.member?(user) # issue归属项目用户没有修改issue的权限跳过
next if issue.pm_project_id.nil? && project.id.to_i != issue.project&.id.to_i
next if issue.pm_project_id.present? && !get_pm_issue_data(user, project.owner, issue.pm_project_id, issue.id) # issue是组织下工作项不具备组织的访问权限跳过
issue_project = issue.project || Project.new(id: 0, user_id: 0, name: 'pm_mm', identifier: 'pm_mm', is_public:true)
if issue.pm_project_id.present?
Api::Pm::Issues::UpdateService.call(issue_project, issue, {status_id: status_id}, user, "Project##{project.id}@#{commitsha}")
else
Api::V1::Issues::UpdateService.call(issue_project, issue, {status_id: status_id}, user, "Project##{project.id}@#{commitsha}")
end
end
end
end

View File

@ -6,7 +6,6 @@ class OpenProjectDevOpsJob < ApplicationJob
def perform(project_id, user_id)
project = Project.find_by(id: project_id)
return if project.blank?
return if EduSetting.get("jianmu_devops_url").blank?
user = User.find_by(id: user_id)
code = jianmu_devops_code(project, user)
uri = URI.parse("#{jianmu_devops_url}/activate?code=#{URI.encode_www_form_component(code)}")

View File

@ -8,8 +8,7 @@ class TouchWebhookJob < ApplicationJob
issue = Issue.find_by_id issue_id
sender = User.find_by_id sender_id
return if issue.nil? || sender.nil?
return if issue.project.nil?
issue.project.webhooks.each do |webhook|
issue.project.webhooks.each do |webhook|
next unless webhook.events["events"]["issues"]
_, _, @webhook_task = Webhook::IssueClient.new(webhook, issue, sender,"issues").do_request
Rails.logger.info "Touch Webhook Response result: #{@webhook_task.response_content}"
@ -19,7 +18,6 @@ class TouchWebhookJob < ApplicationJob
issue = Issue.find_by_id issue_id
sender = User.find_by_id sender_id
return if issue.nil? || sender.nil? || !changes.is_a?(Hash) || changes.blank?
return if issue.project.nil?
issue.project.webhooks.each do |webhook|
next unless webhook.events["events"]["issues"]
_, _, @webhook_task = Webhook::IssueClient.new(webhook, issue, sender, "issues", changes.stringify_keys).do_request
@ -31,7 +29,6 @@ class TouchWebhookJob < ApplicationJob
issue = Issue.find_by_id issue_id
sender = User.find_by_id sender_id
return if issue.nil? || sender.nil?
return if issue.project.nil?
issue.project.webhooks.each do |webhook|
next unless webhook.events["events"]["issue_assign"]
_, _, @webhook_task = Webhook::IssueClient.new(webhook, issue, sender, "issue_assign", changes.stringify_keys).do_request
@ -42,8 +39,7 @@ class TouchWebhookJob < ApplicationJob
issue_id, sender_id, changes = args[0], args[1], args[2]
issue = Issue.find_by_id issue_id
sender = User.find_by_id sender_id
return if issue.nil? || sender.nil?
return if issue.project.nil?
return if issue.nil? || sender.nil?
issue.project.webhooks.each do |webhook|
next unless webhook.events["events"]["issue_label"]
_, _, @webhook_task = Webhook::IssueClient.new(webhook, issue, sender, "issue_label", changes.stringify_keys).do_request
@ -57,7 +53,6 @@ class TouchWebhookJob < ApplicationJob
return if issue.nil? || sender.nil?
comment = issue.comment_journals.find_by_id comment_id
return if action_type == 'edited' && comment_json.blank?
return if issue.project.nil?
issue.project.webhooks.each do |webhook|
next unless webhook.events["events"]["issue_comment"]
@ -73,7 +68,6 @@ class TouchWebhookJob < ApplicationJob
return if issue.nil? || pull.nil? || sender.nil?
comment = issue.comment_journals.find_by_id comment_id
return if action_type == 'edited' && comment_json.blank?
return if issue.project.nil?
pull.project.webhooks.each do |webhook|
next unless webhook.events["events"]["pull_request_comment"]

View File

@ -4,7 +4,6 @@ class UpdateProjectTopicJob < ApplicationJob
queue_as :message
def perform(project_id)
return unless $redis_cache.set("UpdateProjectTopicJob:#{project_id}", 1, nx: true, ex: 10.seconds)
project = Project.find_by(id: project_id)
return if project.blank?
begin
@ -26,9 +25,7 @@ class UpdateProjectTopicJob < ApplicationJob
topic_count +=1
end
end
$redis_cache.del("UpdateProjectTopicJob:#{project_id}")
rescue => e
$redis_cache.del("UpdateProjectTopicJob:#{project_id}")
puts "get_repos_languages: error:#{e.message}"
end
end

View File

@ -1,70 +0,0 @@
require 'oauth2'
module Ci4s::Service
module_function
def client_id
config = Rails.application.config_for(:configuration)
config.dig("oauth", "ci4s", "client_id")
end
def client_secret
config = Rails.application.config_for(:configuration)
config.dig("oauth", "ci4s", "client_secret")
end
def base_url
config = Rails.application.config_for(:configuration)
config.dig("oauth", "ci4s", "base_url")
end
def redirect_uri
config = Rails.application.config_for(:configuration)
config.dig("oauth", "ci4s", "redirect_uri")
end
def oauth_url
"#{base_url}/oauth/authorize?client_id=#{client_id}&redirect_uri=#{URI.encode_www_form_component(redirect_uri)}&response_type=code&grant_type=authorization_code"
end
def request(method, url, params)
begin
Rails.logger.info("[Ci4sOauth] [#{method.to_s.upcase}] #{url} || #{params}")
client ||= begin
Faraday.new(url: base_url) do |req|
req.request :url_encoded
req.headers['Content-Type'] = 'application/json'
req.response :logger # 显示日志
req.adapter Faraday.default_adapter
req.authorization :Bearer, params[:access_token]
req.headers['Authorization']
end
end
response = client.public_send(method, url, params)
result = JSON.parse(response.body)
Rails.logger.info("[Ci4sOauth] [#{response.status}] #{result}")
result
rescue Exception => e
raise Gitlink::TipException.new(e.message)
end
end
def access_token(code)
begin
Rails.logger.info("[Ci4sOauth] [code] #{code} ")
Rails.logger.info("[Ci4sOauth] [redirect_uri] #{redirect_uri} ")
client = OAuth2::Client.new(client_id, client_secret, site: base_url)
result = client.auth_code.get_token(code, redirect_uri: redirect_uri).to_hash
return result
rescue Exception => e
raise Gitlink::TipException.new(e.message)
end
end
def user_info(access_token)
request(:get, '/user/info', {access_token: access_token})
end
end

View File

@ -7,7 +7,7 @@ module EducoderOauth::Service
begin
Rails.logger.info("[EducoderOauth] [#{method.to_s.upcase}] #{url} || #{params}")
client = Faraday.new(url: EducoderOauth.base_url, headers: {'X-EDU-Timestamp' => "#{Time.now.to_i}"})
client = Faraday.new(url: EducoderOauth.base_url)
response = client.public_send(method, url, params)
result = JSON.parse(response.body)

View File

@ -1,44 +0,0 @@
module SonarService
def build_sonar_content(owner,project_id,lang_keys)
lang_map = {
'Java' => :java,
'Python' => :python,
'JavaScript' => :js,
'TypeScript' => :ts,
'C++' => :cpp,
'C' => :cpp
}
detected_langs = lang_keys.map { |l| lang_map[l] }.compact.to_set
lines = []
lines << "sonar.projectKey=#{owner}-#{project_id}"
lines << "sonar.projectVersion=1.0"
lines << "sonar.sourceEncoding=UTF-8"
lines << "sonar.sources=."
lines << "sonar.exclusions=**/test/**,**/tests/**,**/vendor/**,**/node_modules/**,**/__pycache__/**"
if detected_langs.include?(:java)
lines << "sonar.java.binaries="
end
if detected_langs.include?(:js)
lines << "sonar.javascript.lcov.reportPaths=coverage/lcov.info"
end
if detected_langs.include?(:ts)
lines << "sonar.typescript.tsconfigPath=tsconfig.json"
end
if detected_langs.include?(:python)
lines << "sonar.python.coverage.reportPaths=coverage.xml"
end
if detected_langs.include?(:cpp)
lines << "sonar.cxx.file.suffixes=.cpp,.c,.cc,.h,.hpp,.hh"
lines << "sonar.cxx.errorRecoveryEnabled=true"
end
lines.join("\n")
end
end

View File

@ -17,15 +17,11 @@
# created_at :datetime not null
# updated_at :datetime not null
# label :string(255)
# node_type :string(255)
# is_mutil_link :boolean
# link_type :string(255)
#
# Indexes
#
# by_name (name)
# index_action_nodes_on_action_types_id (action_node_types_id)
# index_action_nodes_on_user_id (user_id)
# index_action_nodes_on_action_node_types_id (action_node_types_id)
# index_action_nodes_on_user_id (user_id)
#
class Action::Node < ApplicationRecord
@ -38,7 +34,7 @@ class Action::Node < ApplicationRecord
belongs_to :user, optional: true
attr_accessor :cust_name, :run_values, :input_values, :parent_node_id, :sub_nodes, :link_type_array, :node_id
attr_accessor :cust_name, :run_values, :input_values
validates :name, presence: { message: "不能为空" }
validates :full_name, length: { maximum: 200, too_long: "不能超过200个字符" }
@ -46,7 +42,6 @@ class Action::Node < ApplicationRecord
validates :description, length: { maximum: 65535, too_long: "不能超过65535个字符"}
def content_yaml
"foo".to_yaml
<<~YAML

View File

@ -33,7 +33,7 @@ class Action::Pipeline < ApplicationRecord
belongs_to :user, optional: true
belongs_to :project
validates :pipeline_name, presence: { message: "不能为空" }
validates :name, presence: { message: "不能为空" }
validates :json, length: { maximum: 65535, too_long: "不能超过65535个字符"}
validates :yaml, length: { maximum: 65535, too_long: "不能超过65535个字符"}
end

View File

@ -1,25 +0,0 @@
# == Schema Information
#
# Table name: action_pipeline_results
#
# id :integer not null, primary key
# project_id :integer
# run_id :integer
# step_id :string(255)
# job_name :string(255)
# job_show_type :string(255)
# job_result :text(65535)
# created_at :datetime not null
# updated_at :datetime not null
#
# Indexes
#
# index_action_pipeline_results_on_project_id (project_id)
# index_action_pipeline_results_on_run_id (run_id)
#
class Action::PipelineResult < ApplicationRecord
self.table_name = 'action_pipeline_results'
belongs_to :project
end

View File

@ -24,7 +24,7 @@
class CommitLog < ApplicationRecord
belongs_to :user
belongs_to :project
# belongs_to :repository
belongs_to :repository
has_many :project_trends, as: :trend, dependent: :destroy

View File

@ -6,8 +6,8 @@ module Matchable
scope :with_project_language, ->(language_id) { where(project_language_id: language_id) unless language_id.blank? }
scope :with_project_type, ->(project_type) { where(project_type: project_type) if Project.project_types.include?(project_type) }
scope :by_name_or_identifier, ->(search) { where("name like :search or identifier LIKE :search", :search => "%#{search.split(" ").join('|')}%") unless search.blank? }
scope :with_project_topic, ->(topic_id) {left_outer_joins(:project_topics).where(project_topics: {id: topic_id}) unless topic_id.blank?}
scope :with_project_topic_name, ->(topic_name) {left_outer_joins(:project_topics).where(project_topics: {name: topic_name}) unless topic_name.blank?}
scope :with_project_topic, ->(topic_id) {joins(:project_topics).where(project_topics: {id: topic_id}) unless topic_id.blank?}
scope :with_project_topic_name, ->(topic_name) {joins(:project_topics).where(project_topics: {name: topic_name}) unless topic_name.blank?}
end
end

View File

@ -1,23 +1,22 @@
# == Schema Information
#
# Table name: edu_settings
#
# id :integer not null, primary key
# name :string(255)
# value :string(255)
# created_at :datetime not null
# updated_at :datetime not null
# description :string(255)
#
# Indexes
#
# index_edu_settings_on_name (name) UNIQUE
#
# == Schema Information
#
# Table name: edu_settings
#
# id :integer not null, primary key
# name :string(255)
# value :string(255)
# created_at :datetime not null
# updated_at :datetime not null
# description :string(255)
#
# Indexes
#
# index_edu_settings_on_name (name) UNIQUE
#
class EduSetting < ApplicationRecord
after_commit :expire_value_cache, on: [:create, :update]
after_commit :clear_value_cache, on: :destroy
after_commit :expire_value_cache
scope :by_search, -> (keyword){ where("name LIKE :keyword OR value LIKE :keyword", keyword: "%#{strip_param(keyword)}%") unless strip_param(keyword).blank? }
@ -26,11 +25,7 @@ class EduSetting < ApplicationRecord
end
def self.get(key)
begin
Rails.cache.fetch(value_cache_key(key), expires_in: 1.days) do
find_by_name(key.to_s)&.value
end
rescue Exception => e
Rails.cache.fetch(value_cache_key(key), expires_in: 1.days) do
find_by_name(key.to_s)&.value
end
end
@ -46,8 +41,4 @@ class EduSetting < ApplicationRecord
def expire_value_cache
Rails.cache.write(value_cache_key, value)
end
def clear_value_cache
Rails.cache.delete(value_cache_key)
end
end

View File

@ -1,9 +0,0 @@
class Gitea::ActionRun < Gitea::Base
self.inheritance_column = nil # FIX The single-table inheritance mechanism failed
# establish_connection :gitea_db
self.table_name = "action_run"
# belongs_to :user, class_name: '::User', primary_key: :gitea_uid, foreign_key: :owner_id, optional: true
end

View File

@ -1,9 +0,0 @@
class Gitea::RepoUnit < Gitea::Base
self.inheritance_column = nil # FIX The single-table inheritance mechanism failed
# establish_connection :gitea_db
self.table_name = "repo_unit"
# belongs_to :user, class_name: '::User', primary_key: :gitea_uid, foreign_key: :owner_id, optional: true
end

View File

@ -26,7 +26,7 @@ class IdentityVerification < ApplicationRecord
after_create do
Attachment.where(uuid:[card_front,card_back,hold_card_front,hold_card_back]).update_all(is_public:0)
end
after_save do
if state == "已通过"
user.update(id_card_verify: true, website_permission: true)

View File

@ -102,7 +102,6 @@ class Issue < ApplicationRecord
scope :issue_issue, ->{where(issue_classify: [nil, 'issue'])}
scope :issue_pull_request, ->{where(issue_classify: 'pull_request')}
scope :issue_index_includes, ->{includes(:tracker, :priority, :version, :issue_status, :journals,:issue_tags,user: :user_extension)}
scope :pm_includes, -> {includes(:project, :show_issue_tags, :issue_status, :priority, :version, :user, :show_assigners, :comment_journals, :operate_journals)}
scope :closed, ->{where(status_id: 5)}
scope :opened, ->{where.not(status_id: 5)}
after_create :incre_project_common, :incre_user_statistic, :incre_platform_statistic
@ -298,38 +297,6 @@ class Issue < ApplicationRecord
self.project.decrement!(:closed_issues_count) if self.status_id == 5 && self.project.present?
end
# def self.find_issues_by_pm(enterprise_identifier, pm_issue_type)
# case pm_issue_type.to_i
# when 1
# Issue.issue_issue.where(enterprise_identifier: enterprise_identifier)
# .where(pm_issue_type: pm_issue_type)
# .where(pm_issue_type_index1: index)
# when 2
# Issue.issue_issue.where(enterprise_identifier: enterprise_identifier)
# .where(pm_issue_type: pm_issue_type)
# .where(pm_issue_type_index2: index)
# when 3
# Issue.issue_issue.where(enterprise_identifier: enterprise_identifier)
# .where(pm_issue_type: pm_issue_type)
# .where(pm_issue_type_index3: index)
# end
# end
#
# def self.build_pm_index(enterprise_identifier, pm_issue_type)
# last_issue = Issue.find_issues_by_pm(enterprise_identifier, pm_issue_type).order("pm_issue_type_index#{pm_issue_type.to_i} asc").last
# deleted_issue_count = ($redis_cache.hget("pm_issue_cache_delete_count", enterprise_identifier) || 0).to_i
#
# last_issue.send("pm_issue_type_index#{pm_issue_type.to_i}").present? ? last_issue.send("pm_issue_type_index#{pm_issue_type.to_i}") + deleted_issue_count : 0
# end
#
# def incre_pm_issue_cache_delete_count(count=1)
# $redis_cache.hincrby("pm_issue_cache_delete_count", self.enterprise_identifier, count)
# end
#
# def del_pm_issue_cache_delete_count
# $redis_cache.hdel("pm_issue_cache_delete_count", self.enterprise_identifier)
# end
def send_update_message_to_notice_system
SendTemplateMessageJob.perform_later('IssueExpire', self.id) if Site.has_notice_menu? && self.due_date == Date.today + 1.days
end
@ -356,7 +323,7 @@ class Issue < ApplicationRecord
end
end
def to_builder
def to_builder
Jbuilder.new do |issue|
issue.(self, :id, :project_issues_index, :subject, :description, :branch_name, :start_date, :due_date)
issue.created_at self.created_on.strftime('%Y-%m-%d %H:%M')

View File

@ -22,7 +22,6 @@
# resolveer_id :integer
# need_respond :boolean default("0")
# updated_on :datetime
# operate_by :string(255) default("Issue")
#
# Indexes
#
@ -52,7 +51,6 @@ class Journal < ApplicationRecord
scope :journal_includes, ->{includes(:user, :journal_details, :attachments)}
scope :parent_journals, ->{where(parent_id: nil)}
scope :children_journals, lambda{|journal_id| where(parent_id: journal_id)}
scope :operate_journals, ->{where(notes: nil)}
enum state: {opened: 0, resolved: 1, disabled: 2}
@ -84,17 +82,6 @@ class Journal < ApplicationRecord
end
end
def operate_by_content
return '' if self.operate_by == "Issue"
if self.operate_by.starts_with?("Project#")
project_id, commit_sha = self.operate_by.scan(/#(\d+).*?@(\w+)/)[0]
project =Project.find_by_id(project_id)
return "通过 #{project&.owner&.real_name}/#{project&.name} 提交 <a href=\"#{Rails.application.config_for(:configuration)['platform_url']}/#{project&.owner&.login}/#{project&.identifier}/commits/#{commit_sha}\">#{commit_sha[0...10]}</a>"
end
rescue
return ''
end
def pm_operate_category
detail = self.journal_details.take
if %w(requirement task bug).include?(detail.property) && detail.prop_key.to_s == "1"
@ -104,23 +91,8 @@ class Journal < ApplicationRecord
end
end
def pm_dashboard_operate_content
content = self.pm_operate_content
if content.start_with?('创建了')
content += "<b>#{self.issue.subject}</b>"
else
prefix = '将'
prefix += "计划" if self.issue.pm_issue_type == 1
prefix += "任务" if self.issue.pm_issue_type == 2
prefix += "缺陷" if self.issue.pm_issue_type == 3
prefix += "<b>#{self.issue.subject}</b>"
content = prefix + content.sub('将', '的')
end
content
end
def pm_operate_content
content = "#{operate_by_content}"
content = ""
detail = self.journal_details.take
case detail.property
when 'requirement'
@ -181,7 +153,7 @@ class Journal < ApplicationRecord
end
return content
else
content += "创建了需求"
return "创建了需求"
end
when 'task'
case detail.prop_key
@ -241,7 +213,7 @@ class Journal < ApplicationRecord
end
return content
else
content += "创建了任务"
return "创建了任务"
end
when 'bug'
case detail.prop_key
@ -301,14 +273,14 @@ class Journal < ApplicationRecord
end
return content
else
content += "创建了缺陷"
return "创建了缺陷"
end
when 'attr'
case detail.prop_key
when 'subject'
content += "修改了<b>标题</b>"
return "修改了<b>标题</b>"
when 'description'
content += "修改了<b>正文</b>"
return "修改了<b>正文</b>"
when 'priority_id'
old_value = IssuePriority.find_by_id(detail.old_value)&.name
new_value = IssuePriority.find_by_id(detail.value)&.name
@ -518,23 +490,21 @@ class Journal < ApplicationRecord
issue = self.issue
case issue.pm_issue_type
when 1
content += "创建了需求"
return "创建了需求"
when 2
content += "创建了任务"
return "创建了任务"
when 3
content += "创建了缺陷"
return "创建了缺陷"
end
end
return content
end
def operate_content
content = "#{operate_by_content}"
content = ""
detail = self.journal_details.take
case detail.property
when 'issue'
content += "创建了<b>疑修</b>"
return "创建了<b>疑修</b>"
when 'attachment'
old_value = Attachment.where("BINARY id in (?) or uuid in (?)", detail.old_value.to_s.split(","), detail.old_value.to_s.split(",")).pluck(:filename).join("")
new_value = Attachment.where("BINARY id in (?) or uuid in (?)", detail.value.to_s.split(","), detail.value.to_s.split(",")).pluck(:filename).join("")
@ -563,12 +533,12 @@ class Journal < ApplicationRecord
content += "将负责人由<b>#{old_value}</b>更改为<b>#{new_value}</b>"
end
when 'attr'
content += ""
content = ""
case detail.prop_key
when 'subject'
content += "修改了<b>标题</b>"
return "修改了<b>标题</b>"
when 'description'
content += "修改了<b>描述</b>"
return "修改了<b>描述</b>"
when 'status_id'
old_value = IssueStatus.find_by_id(detail.old_value)&.name
new_value = IssueStatus.find_by_id(detail.value)&.name

View File

@ -1,27 +0,0 @@
# == Schema Information
#
# Table name: open_users
#
# id :integer not null, primary key
# user_id :integer
# type :string(255)
# uid :string(255)
# created_at :datetime not null
# updated_at :datetime not null
# extra :text(65535)
#
# Indexes
#
# index_open_users_on_type_and_uid (type,uid) UNIQUE
# index_open_users_on_user_id (user_id)
#
class OpenUsers::Ci4s < OpenUser
def nickname
extra&.[]('username')
end
def en_type
'ci4s'
end
end

View File

@ -131,9 +131,9 @@ class Project < ApplicationRecord
has_many :pinned_projects, dependent: :destroy
has_many :has_pinned_users, through: :pinned_projects, source: :owner
has_many :webhooks, class_name: "Gitea::Webhook", primary_key: :gpid, foreign_key: :repo_id
has_many :user_trace_tasks, dependent: :destroy
has_many :user_trace_tasks, dependent: :destroy
has_many :project_invite_links, dependent: :destroy
has_many :project_topic_ralates, dependent: :destroy
has_many :project_topic_ralates, dependent: :destroy
has_many :project_topics, through: :project_topic_ralates
has_many :commit_logs, dependent: :destroy
has_many :daily_project_statistics, dependent: :destroy
@ -150,12 +150,6 @@ class Project < ApplicationRecord
scope :recommend, -> { visible.project_statics_select.where(recommend: true) }
scope :pinned, -> {where(is_pinned: true)}
scope :like, lambda { |keywords|
# 表情处理
keywords = keywords.to_s.each_char.select { |c| c.bytes.first < 240 }.join('')
sql = "name LIKE :search OR identifier LIKE :search"
where(sql, :search => "%#{keywords.strip}%") unless keywords.blank?
}
delegate :content, to: :project_detail, allow_nil: true
delegate :name, to: :license, prefix: true, allow_nil: true
@ -252,11 +246,11 @@ class Project < ApplicationRecord
def set_recommend_and_is_pinned
self.recommend = self.recommend_index.zero? ? false : true
# 私有项目不允许设置精选和推荐
# unless self.is_public
# self.recommend = false
# self.recommend_index = 0
# self.is_pinned = false
# end
unless self.is_public
self.recommend = false
self.recommend_index = 0
self.is_pinned = false
end
end
def self.search_project(search)
@ -400,13 +394,11 @@ class Project < ApplicationRecord
user = Owner.find_by_login namespace_path
user = User.new(login: namespace_path) if user.nil?
project = user&.projects&.find_by(identifier: identifier) || Project.find_by(identifier: "#{namespace_path}/#{identifier}")
user = User.new(login: namespace_path) if user.nil?
if identifier.end_with?('.json')
project = user&.projects&.find_by(identifier: identifier) || Project.find_by(identifier: "#{namespace_path}/#{identifier}")
identifier = identifier.sub(/.*\K.json/, '')
project = user&.projects&.find_by(identifier: identifier) || Project.find_by(identifier: "#{namespace_path}/#{identifier}")
else
else
project = user&.projects&.find_by(identifier: identifier) || Project.find_by(identifier: "#{namespace_path}/#{identifier}")
end
return nil if project.blank?
@ -453,46 +445,36 @@ class Project < ApplicationRecord
end
def get_last_project_issues_index
last_issue = self.issues.issue_issue.order(project_issues_index: :asc).last
last_issue = self.issues.issue_issue.last
deleted_issue_count = ($redis_cache.hget("issue_cache_delete_count", self.id) || 0).to_i
last_issue&.project_issues_index.present? ? last_issue.project_issues_index + deleted_issue_count : 0
end
def incre_project_issue_cache_delete_count(count=1)
$redis_cache.hincrby("issue_cache_delete_count", self.id, count)
$redis_cache.hincrby("issue_cache_delete_count", self.id, count)
end
def del_project_issue_cache_delete_count
$redis_cache.hdel("issue_cache_delete_count", self.id)
$redis_cache.hdel("issue_cache_delete_count", self.id)
end
def open_portrait
EduSetting.get("open_portrait_projects").present? ? EduSetting.get("open_portrait_projects").split(",").include?(self.id.to_s) : false
end
def actionable
return false if EduSetting.get("project_user_actionable").nil?
return EduSetting.get("project_user_actionable").split(",").include?(self.owner&.login)
end
def has_pull_request(branch_name)
return true if self.pull_requests.opening.where(head: branch_name).present? || self.pull_requests.opening.where(base: branch_name).present?
if self.forked_from_project_id.present?
return true if self.fork_project.pull_requests.opening.where(head: branch_name).present? || self.fork_project.pull_requests.opening.where(base: branch_name).present?
end
return false
end
def is_need_apply
return false if EduSetting.get("project_need_apply").nil?
return EduSetting.get("project_need_apply").split(",").include?(self.id.to_s)
end
def self.mindspore_contributors
def self.mindspore_contributors
cache_result = $redis_cache.get("ProjectMindsporeContributors")
if cache_result.nil?
if cache_result.nil?
contributors = []
file = File.open('public/mindspore_authors', 'r')
file.each_line do |l|
@ -500,12 +482,12 @@ class Project < ApplicationRecord
email = itemArray[0]
username = itemArray[1]
commits = itemArray[2].to_i
user = User.find_by(login: username, mail: email)
user = User.find_by(login: username) if user.nil?
user = User.find_by(login: username, mail: email)
user = User.find_by(login: username) if user.nil?
user = User.find_by(mail: email) if user.nil?
# next if user.nil?
search_contributor = contributors.select{|con| con["id"]==user.id}[0]
if search_contributor.present?
if search_contributor.present?
search_contributor["contributions"] += commits
else
contributors << {contributions: commits, name: username, login: username, email: email, id: user&.id}.stringify_keys
@ -516,7 +498,7 @@ class Project < ApplicationRecord
$redis_cache.set("ProjectMindsporeContributors", contributors.to_json)
return contributors
else
else
return JSON.parse(cache_result)
end
end
@ -533,9 +515,9 @@ class Project < ApplicationRecord
project.description Nokogiri::HTML(self.description).text
project.visits self.visits
project.praises_count self.praises_count.to_i
project.watchers_count self.watchers_count.to_i
project.issues_count self.issues_count.to_i
project.pull_requests_count self.pull_requests_count.to_i
project.watchers_count self.watchers_count.to_i
project.issues_count self.issues_count.to_i
project.pull_requests_count self.pull_requests_count.to_i
project.forked_count self.forked_count.to_i
project.is_public self.is_public
project.mirror_url self.repository&.mirror_url

View File

@ -19,8 +19,4 @@ class ProjectTopicRalate < ApplicationRecord
belongs_to :project_topic, counter_cache: :projects_count
belongs_to :project
validates :project_id, uniqueness: { scope: :project_topic_id }
end

View File

@ -23,7 +23,7 @@ class ProjectUnit < ApplicationRecord
def self.init_types(project_id, project_type='common')
unit_types = project_type == 'sync_mirror' ? ProjectUnit::unit_types.except("pulls") : ProjectUnit::unit_types
unit_types = unit_types.except("dataset") unless EduSetting.get("is_local") == "true"
unit_types = unit_types.except("dataset")
unit_types.each do |_, v|
self.create!(project_id: project_id, unit_type: v)
end

View File

@ -34,7 +34,7 @@ class PullRequest < ApplicationRecord
belongs_to :issue
belongs_to :user
belongs_to :project, counter_cache: true, touch: true, optional: true
belongs_to :project, counter_cache: true, touch: true
belongs_to :fork_project, class_name: 'Project', foreign_key: :fork_project_id, optional: true
has_many :pull_request_assigns, foreign_key: :pull_request_id
has_many :pull_request_tags, foreign_key: :pull_request_id

View File

@ -137,7 +137,7 @@ class User < Owner
has_many :tidings, :dependent => :destroy
# has_many :journals_for_messages, :as => :jour, :dependent => :destroy
has_many :attachments,foreign_key: :author_id
has_many :attachments,foreign_key: :author_id, :dependent => :destroy
has_one :ci_cloud_account, class_name: 'Ci::CloudAccount', dependent: :destroy
@ -160,7 +160,7 @@ class User < Owner
# 教学案例
# has_many :libraries, dependent: :destroy
has_many :project_trends
has_many :project_trends, dependent: :destroy
has_many :oauths , dependent: :destroy
has_many :organization_users, dependent: :destroy
@ -168,8 +168,8 @@ class User < Owner
has_many :pinned_projects, dependent: :destroy
has_many :is_pinned_projects, through: :pinned_projects, source: :project
accepts_nested_attributes_for :is_pinned_projects
has_many :issues, foreign_key: :author_id
has_many :pull_requests
has_many :issues, dependent: :destroy, foreign_key: :author_id
has_many :pull_requests, dependent: :destroy
has_many :public_keys, class_name: "Gitea::PublicKey",primary_key: :gitea_uid, foreign_key: :owner_id, dependent: :destroy
has_one :user_template_message_setting, dependent: :destroy
@ -692,11 +692,7 @@ class User < Owner
# Returns the user who matches the given autologin +key+ or nil
def self.try_to_autologin(key)
user = Token.find_active_user('autologin', key)
if user
Rails.cache.fetch("user::update::last_login_on::#{user.id}",:expires_in => 5.minutes) do
user.update(last_login_on: Time.now)
end
end
user.update(last_login_on: Time.now) if user
user
end

View File

@ -10,10 +10,6 @@
# updated_at :datetime not null
# ip :string(255)
# data_bank :text(65535)
# login :string(255)
# phone :string(255)
# email :string(255)
# memo :text(65535)
#
# Indexes
#
@ -23,76 +19,5 @@
# index_user_actions_on_user_id (user_id)
#
class UserAction < ApplicationRecord
after_save :add_user_info
serialize :data_bank, JSON
def action_name
case action_type
when "DestroyUser" then "用户注销"
when "DestroyProject" then "删除项目"
when "Login" then "登录"
when "Logout" then "退出登录"
else self.action_type
end
end
def opt_user_name
user = User.find_by(id: self.user_id)
if user.present?
user&.login
else
del_user = UserAction.find_by(action_type: "DestroyUser", action_id: self.user_id)
del_user.present? ? del_user.user.login : "不存在用户:#{user_id}"
end
end
def action_info
case action_type
when "DestroyUser" then "账号:#{user&.login}<br/>邮箱:#{user&.mail}<br/>手机号:#{user&.phone}<br/>昵称:#{user&.nickname}<br/>"
when "DestroyProject" then "项目名称:#{project&.name}<br/>项目标识:#{project&.identifier}<br/>"
else "--"
end
end
def user
action_user = if action_type == "DestroyUser" && data_bank.present?
build_mode("User")
else
User.find_by(id: self.user_id)
end
action_user
end
def project
action_project = if action_type == "DestroyProject" && data_bank.present?
build_mode("Project")
else
Project.find_by(id: self.action_id)
end
action_project
end
def build_mode(model_name)
model = model_name.constantize.new
model_name.constantize.column_names.each do |col|
data = self.data_bank.class == String ? JSON.parse(self.data_bank) : self.data_bank
model[col] = data[col]
end
model
rescue =>err
return nil
end
private
def add_user_info
if self.login.blank?
if user.present?
self.login = user.login
self.email = user.mail
self.phone = user.phone
end
end
end
end
class UserAction < ApplicationRecord
end

View File

@ -24,26 +24,6 @@ class ApplicationQuery
end
end
# find one repo that a user has tokens
def find_one_balance_with_token(user_id, project_id)
# return 3 statuses: UnknownErr/ResUserNotExisted/Success
params = {
"request-type": "query user balance of single repo",
"username": user_id.to_s,
"token_name": project_id.to_s
}.to_json
Rails.logger.info "query user balance of single repo params======= #{params}"
resp_body = Blockchain::InvokeBlockchainApi.call(params)
Rails.logger.info "resp_body======= #{resp_body}"
if resp_body['status'] == 0
return resp_body
elsif resp_body['status'] == 100
return 0 # 找不到用户返回0
else
raise "区块链接口请求失败."
end
end
# find one repo that a user has tokens
def find_one_balance(user_id, project_id)

Some files were not shown because too many files have changed in this diff Show More