diff --git a/app/controllers/accounts_controller.rb b/app/controllers/accounts_controller.rb
index 14d59af77..e0508efe8 100644
--- a/app/controllers/accounts_controller.rb
+++ b/app/controllers/accounts_controller.rb
@@ -1,5 +1,5 @@
class AccountsController < ApplicationController
- before_action :require_login, only: [:login_check, :simple_update]
+ before_action :require_login, only: [:login_check, :simple_update, :change_password]
include ApplicationHelper
#skip_before_action :check_account, :only => [:logout]
@@ -224,6 +224,7 @@ class AccountsController < ApplicationController
def change_password
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?(params[:old_password])
diff --git a/app/controllers/admins/projects_controller.rb b/app/controllers/admins/projects_controller.rb
index f5f210a0d..79582cb7c 100644
--- a/app/controllers/admins/projects_controller.rb
+++ b/app/controllers/admins/projects_controller.rb
@@ -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("name like ? OR identifier LIKE ?", "%#{search}%", "%#{search}%").order("#{sort_by} #{sort_direction}")
+ projects = Project.where("id = ? OR name like ? OR identifier LIKE ?", search, "%#{search}%", "%#{search}%").order("#{sort_by} #{sort_direction}")
case params[:category]
when 'public'
projects = projects.where(is_public: true)
diff --git a/app/controllers/admins/user_actions_controller.rb b/app/controllers/admins/user_actions_controller.rb
new file mode 100644
index 000000000..ff52d5a1a
--- /dev/null
+++ b/app/controllers/admins/user_actions_controller.rb
@@ -0,0 +1,14 @@
+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
diff --git a/app/controllers/admins/users_controller.rb b/app/controllers/admins/users_controller.rb
index e544cfb8e..f552c9cd1 100644
--- a/app/controllers/admins/users_controller.rb
+++ b/app/controllers/admins/users_controller.rb
@@ -27,10 +27,30 @@ 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)
- @user.destroy!
- Gitea::User::DeleteService.call(@user.login)
-
- render_delete_success
+ # 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
end
def lock
diff --git a/app/controllers/api/v1/users_controller.rb b/app/controllers/api/v1/users_controller.rb
index 47087c523..09c5a3276 100644
--- a/app/controllers/api/v1/users_controller.rb
+++ b/app/controllers/api/v1/users_controller.rb
@@ -115,4 +115,28 @@ 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
+ return tip_exception(-1, "密码不正确.") unless @observe_user.check_password?(params[: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
\ No newline at end of file
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 52387cbbd..d9dd9e2e6 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -376,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)
+ set_autologin_cookie(autologin_user) if autologin_user.present?
end
autologin_user
end
diff --git a/app/controllers/concerns/login_helper.rb b/app/controllers/concerns/login_helper.rb
index c0e8d01c0..c3b3ecc92 100644
--- a/app/controllers/concerns/login_helper.rb
+++ b/app/controllers/concerns/login_helper.rb
@@ -73,6 +73,17 @@ 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
diff --git a/app/controllers/owners_controller.rb b/app/controllers/owners_controller.rb
index 28a5210d5..ad3a70423 100644
--- a/app/controllers/owners_controller.rb
+++ b/app/controllers/owners_controller.rb
@@ -11,7 +11,10 @@ class OwnersController < ApplicationController
end
def show
- @owner = Owner.find_by(login: params[:id]) || Owner.find_by(id: params[:id])
+ # 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?
return render_not_found unless @owner.present?
# 组织
if @owner.is_a?(Organization)
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index 202bae458..4724224e8 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -253,6 +253,7 @@ 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!
@@ -365,7 +366,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)
+ @attachments = Attachment.where(id: attachment_ids).or(Attachment.where(uuid: attachment_ids))
@attachments.update_all(
container_id: @project_detail.id,
container_type: @project_detail.model_name.name,
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index 27895a758..761a88fa8 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -714,6 +714,7 @@ 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
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index d670e9a0d..bab9ee9b2 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -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
diff --git a/app/helpers/avatar_helper.rb b/app/helpers/avatar_helper.rb
index b703e1b4e..ad0ec0cde 100644
--- a/app/helpers/avatar_helper.rb
+++ b/app/helpers/avatar_helper.rb
@@ -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
diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb
index 0f34b7c1b..80cfa92e0 100644
--- a/app/helpers/projects_helper.rb
+++ b/app/helpers/projects_helper.rb
@@ -129,7 +129,7 @@ module ProjectsHelper
end
def jianmu_devops_url
- EduSetting.get("jianmu_devops_url") || "https://ci-v3.test.jianmuhub.com"
+ EduSetting.get("jianmu_devops_url")
end
diff --git a/app/jobs/open_project_dev_ops_job.rb b/app/jobs/open_project_dev_ops_job.rb
index b3fe99e6f..c5d68a861 100644
--- a/app/jobs/open_project_dev_ops_job.rb
+++ b/app/jobs/open_project_dev_ops_job.rb
@@ -6,6 +6,7 @@ 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)}")
diff --git a/app/models/pull_request.rb b/app/models/pull_request.rb
index 26b4ce2c6..8d276625e 100644
--- a/app/models/pull_request.rb
+++ b/app/models/pull_request.rb
@@ -34,7 +34,7 @@ class PullRequest < ApplicationRecord
belongs_to :issue
belongs_to :user
- belongs_to :project, counter_cache: true, touch: true
+ belongs_to :project, counter_cache: true, touch: true, optional: 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
diff --git a/app/models/user.rb b/app/models/user.rb
index 988f6d8c2..1fee098fb 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -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, :dependent => :destroy
+ has_many :attachments,foreign_key: :author_id
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, dependent: :destroy
+ has_many :project_trends
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, dependent: :destroy, foreign_key: :author_id
- has_many :pull_requests, dependent: :destroy
+ has_many :issues, foreign_key: :author_id
+ has_many :pull_requests
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
diff --git a/app/models/user_action.rb b/app/models/user_action.rb
index b4173fe77..289fa188e 100644
--- a/app/models/user_action.rb
+++ b/app/models/user_action.rb
@@ -10,6 +10,10 @@
# 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
#
@@ -19,5 +23,76 @@
# index_user_actions_on_user_id (user_id)
#
-class UserAction < ApplicationRecord
-end
+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}
邮箱:#{user&.mail}
手机号:#{user&.phone}
昵称:#{user&.nickname}
"
+ when "DestroyProject" then "项目名称:#{project&.name}
项目标识:#{project&.identifier}
"
+ 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
diff --git a/app/queries/application_query.rb b/app/queries/application_query.rb
index e2d7c446f..4d43bfeb6 100644
--- a/app/queries/application_query.rb
+++ b/app/queries/application_query.rb
@@ -24,6 +24,26 @@ 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)
diff --git a/app/queries/blockchain/balance_query.rb b/app/queries/blockchain/balance_query.rb
index 045d2fe8a..d50b38ee6 100644
--- a/app/queries/blockchain/balance_query.rb
+++ b/app/queries/blockchain/balance_query.rb
@@ -11,9 +11,15 @@ class Blockchain::BalanceQuery < ApplicationQuery
if is_current_admin_user
result_list = []
if params[:project_id].present? or params[:keyword].present?
- project_ids = params[:project_id].present? ? [params[:project_id]] : Project.where(user_id: params["user_id"]).like(params[:keyword]).ids
+ token_list, total_count = find_repo_with_token(params["user_id"], 1, 10000)
+ p_ids = []
+ token_list.each do |t|
+ p_ids.push(t['token_name'].to_i)
+ end
+ project_ids = params[:project_id].present? ? [params[:project_id]] : Project.where(id: p_ids).like(params[:keyword]).ids
project_ids.each do |project_id|
- project_balance = find_one_balance(params["user_id"], project_id)
+ project_balance = find_one_balance_with_token(params["user_id"], project_id)
+ next if project_balance == 0
project = Project.find_by(id: project_balance['token_name'].to_i)
if project.present?
owner = User.find_by(id: project.user_id)
diff --git a/app/services/api/pm/issues/update_service.rb b/app/services/api/pm/issues/update_service.rb
index 78d62fb2b..661bd211f 100644
--- a/app/services/api/pm/issues/update_service.rb
+++ b/app/services/api/pm/issues/update_service.rb
@@ -64,7 +64,6 @@ class Api::Pm::Issues::UpdateService < ApplicationService
build_assigner_issue_journal_details unless assigner_ids.nil?# 操作记录
build_attachment_issue_journal_details unless attachment_ids.nil?
build_issue_tag_issue_journal_details unless issue_tag_ids.nil?
- build_issue_project_trends if status_id.present? # 开关时间记录
build_assigner_participants unless assigner_ids.nil? # 负责人
build_edit_participants
build_atme_participants if @atme_receivers.present?
@@ -92,6 +91,7 @@ class Api::Pm::Issues::UpdateService < ApplicationService
build_after_issue_journal_details if @updated_issue.previous_changes.present? # 操作记录
build_previous_issue_changes
+ build_issue_project_trends if status_id.present? # 开关时间记录
build_cirle_blockchain_token if blockchain_token_num.present?
unless @project.id.zero?
# @信息发送
@@ -172,7 +172,7 @@ class Api::Pm::Issues::UpdateService < ApplicationService
def build_issue_project_trends
if @updated_issue.previous_changes["status_id"].present? && @updated_issue.previous_changes["status_id"][1] == 5
- @updated_issue.project_trends.new({user_id: current_user.id, project_id: @project.id, action_type: ProjectTrend::CLOSE})
+ @updated_issue.project_trends.create!({user_id: current_user.id, project_id: @project.id, action_type: ProjectTrend::CLOSE})
end
if @updated_issue.previous_changes["status_id"].present? && @updated_issue.previous_changes["status_id"][0] == 5
@updated_issue.project_trends.where(action_type: ProjectTrend::CLOSE).each(&:destroy!)
diff --git a/app/services/api/v1/issues/update_service.rb b/app/services/api/v1/issues/update_service.rb
index 5f040b25f..10f814300 100644
--- a/app/services/api/v1/issues/update_service.rb
+++ b/app/services/api/v1/issues/update_service.rb
@@ -64,7 +64,6 @@ class Api::V1::Issues::UpdateService < ApplicationService
build_assigner_issue_journal_details unless assigner_ids.nil?# 操作记录
build_attachment_issue_journal_details unless attachment_ids.nil?
build_issue_tag_issue_journal_details unless issue_tag_ids.nil?
- build_issue_project_trends if status_id.present? # 开关时间记录
build_assigner_participants unless assigner_ids.nil? # 负责人
build_edit_participants
build_atme_participants if @atme_receivers.present?
@@ -92,6 +91,7 @@ class Api::V1::Issues::UpdateService < ApplicationService
build_after_issue_journal_details if @updated_issue.previous_changes.present? # 操作记录
build_previous_issue_changes
+ build_issue_project_trends if status_id.present? # 开关时间记录
build_cirle_blockchain_token if blockchain_token_num.present?
unless @project.id.zero?
# @信息发送
@@ -172,7 +172,7 @@ class Api::V1::Issues::UpdateService < ApplicationService
def build_issue_project_trends
if @updated_issue.previous_changes["status_id"].present? && @updated_issue.previous_changes["status_id"][1] == 5
- @updated_issue.project_trends.new({user_id: current_user.id, project_id: @project.id, action_type: ProjectTrend::CLOSE})
+ @updated_issue.project_trends.create!({user_id: current_user.id, project_id: @project.id, action_type: ProjectTrend::CLOSE})
end
if @updated_issue.previous_changes["status_id"].present? && @updated_issue.previous_changes["status_id"][0] == 5
@updated_issue.project_trends.where(action_type: ProjectTrend::CLOSE).each(&:destroy!)
diff --git a/app/services/api/v1/users/delete_user_service.rb b/app/services/api/v1/users/delete_user_service.rb
new file mode 100644
index 000000000..12775eac3
--- /dev/null
+++ b/app/services/api/v1/users/delete_user_service.rb
@@ -0,0 +1,38 @@
+class Api::V1::Users::DeleteUserService < ApplicationService
+ attr_reader :user
+ def initialize(user)
+ @user = user
+ end
+
+ def call
+ begin
+ ActiveRecord::Base.transaction do
+ 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时,仅将用户从组织移除, 一个时直接删除
+ org.team_users.where(user_id: @user.id).destroy_all
+ org.organization_users.where(user_id: @user.id, organization_id: org.id).destroy_all
+ if owner_count == 1
+ if org.team_users.joins(:team).where(user_id: @user.id, teams: { authorize: %w(owner) }).count > 0
+ org.destroy!
+ end
+ end
+ end
+ @user.destroy!
+ del_user_data_by_sql(@user.id)
+ Gitea::User::DeleteService.call(@user.login, true)
+ end
+ return true
+ rescue
+ raise Error, "服务器错误,请联系系统管理员!"
+ end
+ end
+
+ def del_user_data_by_sql(user_id)
+ sql1 = "delete from memos where author_id=#{user_id}"
+ ActiveRecord::Base.connection.execute(sql1)
+ end
+end
\ No newline at end of file
diff --git a/app/services/cache/v2/project_common_service.rb b/app/services/cache/v2/project_common_service.rb
index 1e85f3e08..98a19a80d 100644
--- a/app/services/cache/v2/project_common_service.rb
+++ b/app/services/cache/v2/project_common_service.rb
@@ -102,7 +102,7 @@ class Cache::V2::ProjectCommonService < ApplicationService
return
else
load_project
- return unless @project.is_full_public
+ return unless @project.present? && @project.is_full_public
if @owner_id.present?
if $redis_cache.hget(project_common_key, owner_id_key).nil?
reset_project_owner_id
diff --git a/app/services/gitea/user/delete_service.rb b/app/services/gitea/user/delete_service.rb
index 9011158d2..ce357e3d5 100644
--- a/app/services/gitea/user/delete_service.rb
+++ b/app/services/gitea/user/delete_service.rb
@@ -1,8 +1,9 @@
class Gitea::User::DeleteService < Gitea::ClientService
- attr_reader :username
+ attr_reader :username, :purge
- def initialize(username)
+ def initialize(username, purge = false)
@username = username
+ @purge = purge
end
def call
@@ -20,7 +21,7 @@ class Gitea::User::DeleteService < Gitea::ClientService
end
def request_url
- "/admin/users/#{username}"
+ @purge ? "/admin/users/#{username}?purge=true" : "/admin/users/#{username}"
end
def params
diff --git a/app/views/admins/edu_settings/_list.html.erb b/app/views/admins/edu_settings/_list.html.erb
index a37cc9bef..5dc0e1483 100644
--- a/app/views/admins/edu_settings/_list.html.erb
+++ b/app/views/admins/edu_settings/_list.html.erb
@@ -17,7 +17,7 @@
序号 | +操作类型 | +操作人账号 | +关联基本信息 | +操作时间 | +原因/备注 | +
---|---|---|---|---|---|
<%= list_index_no((params[:page] || 1).to_i, index) %> | +<%= action.action_name %> | ++ <%= link_to "/#{action.user&.login}", target: '_blank' do %> + <%= overflow_hidden_span action.opt_user_name, width: 100 %> + <% end %> | ++ <%= raw action.action_info %> + | +<%= display_text(action.created_at&.strftime('%Y-%m-%d %H:%M')) %> | +<%= action.memo %> | +