From 1e081b5a3e23cb0ef66bf3d6958c18067274d487 Mon Sep 17 00:00:00 2001
From: "vilet.yy"
Date: Sun, 25 Apr 2021 18:41:13 +0800
Subject: [PATCH 01/12] add: transfer project
---
.../applied_transfer_projects_controller.rb | 26 +++++++++++
.../users/applied_messages_controller.rb | 18 ++++++++
.../applied_transfer_projects_controller.rb | 41 ++++++++++++++++++
app/controllers/users_controller.rb | 11 ++++-
...nd_transfer_project_applied_message_job.rb | 34 +++++++++++++++
app/models/applied_message.rb | 5 +++
app/models/applied_transfer_project.rb | 28 ++++++++++++
app/models/owner.rb | 2 +
app/models/project.rb | 4 ++
app/models/user.rb | 4 +-
.../projects/accept_transfer_service.rb | 43 +++++++++++++++++++
.../projects/apply_transfer_service.rb | 41 ++++++++++++++++++
.../projects/cancel_transfer_service.rb | 33 ++++++++++++++
.../projects/refuse_transfer_service.rb | 33 ++++++++++++++
.../organizations/_simple.json.jbuilder | 5 +++
.../_detail.json.jbuilder | 21 +++++++++
.../cancel.json.jbuilder | 1 +
.../create.json.jbuilder | 1 +
.../organizations.json.jbuilder | 4 ++
app/views/repositories/edit.json.jbuilder | 4 +-
app/views/users/_user_simple.json.jbuilder | 1 +
.../applied_messages/_detail.json.jbuilder | 25 +++++++++++
.../applied_messages/index.json.jbuilder | 4 ++
.../accept.json.jbuilder | 1 +
.../index.json.jbuilder | 4 ++
.../refuse.json.jbuilder | 1 +
config/routes.rb | 13 ++++++
...032825_create_applied_transfer_projects.rb | 12 ++++++
28 files changed, 416 insertions(+), 4 deletions(-)
create mode 100644 app/controllers/projects/applied_transfer_projects_controller.rb
create mode 100644 app/controllers/users/applied_messages_controller.rb
create mode 100644 app/controllers/users/applied_transfer_projects_controller.rb
create mode 100644 app/jobs/send_transfer_project_applied_message_job.rb
create mode 100644 app/models/applied_transfer_project.rb
create mode 100644 app/services/projects/accept_transfer_service.rb
create mode 100644 app/services/projects/apply_transfer_service.rb
create mode 100644 app/services/projects/cancel_transfer_service.rb
create mode 100644 app/services/projects/refuse_transfer_service.rb
create mode 100644 app/views/organizations/organizations/_simple.json.jbuilder
create mode 100644 app/views/projects/applied_transfer_projects/_detail.json.jbuilder
create mode 100644 app/views/projects/applied_transfer_projects/cancel.json.jbuilder
create mode 100644 app/views/projects/applied_transfer_projects/create.json.jbuilder
create mode 100644 app/views/projects/applied_transfer_projects/organizations.json.jbuilder
create mode 100644 app/views/users/applied_messages/_detail.json.jbuilder
create mode 100644 app/views/users/applied_messages/index.json.jbuilder
create mode 100644 app/views/users/applied_transfer_projects/accept.json.jbuilder
create mode 100644 app/views/users/applied_transfer_projects/index.json.jbuilder
create mode 100644 app/views/users/applied_transfer_projects/refuse.json.jbuilder
create mode 100644 db/migrate/20210425032825_create_applied_transfer_projects.rb
diff --git a/app/controllers/projects/applied_transfer_projects_controller.rb b/app/controllers/projects/applied_transfer_projects_controller.rb
new file mode 100644
index 000000000..887949f8d
--- /dev/null
+++ b/app/controllers/projects/applied_transfer_projects_controller.rb
@@ -0,0 +1,26 @@
+class Projects::AppliedTransferProjectsController < Projects::BaseController
+ before_action :check_auth
+
+ def organizations
+ @organizations = Organization.includes(:organization_extension).joins(team_users: :team).where(team_users: {user_id: current_user.id}, teams: {authorize: %w(admin owner)})
+ end
+
+ def create
+ @applied_transfer_project = Projects::ApplyTransferService.call(current_user, @project, params[:owner_id])
+ rescue Exception => e
+ uid_logger_error(e.message)
+ tip_exception(e.message)
+ end
+
+ def cancel
+ @applied_transfer_project = Projects::CancelTransferService.call(current_user, @project)
+ rescue Exception => e
+ uid_logger_error(e.message)
+ tip_exception(e.message)
+ end
+
+ private
+ def check_auth
+ return render_forbidden unless current_user.admin? ||@project.owner?(current_user)
+ end
+end
\ No newline at end of file
diff --git a/app/controllers/users/applied_messages_controller.rb b/app/controllers/users/applied_messages_controller.rb
new file mode 100644
index 000000000..e80cabf92
--- /dev/null
+++ b/app/controllers/users/applied_messages_controller.rb
@@ -0,0 +1,18 @@
+class Users::AppliedMessagesController < Users::BaseController
+ before_action :check_auth
+ after_action :view_messages, only: [:index]
+
+ def index
+ @applied_messages = @_observed_user.applied_messages.order(viewed: :asc, created_at: :desc)
+ @applied_messages = paginate @applied_messages
+ end
+
+ private
+ def check_auth
+ return render_forbidden unless observed_logged_user?
+ end
+
+ def view_messages
+ @applied_messages.update_all(viewed: 'viewed')
+ end
+end
\ No newline at end of file
diff --git a/app/controllers/users/applied_transfer_projects_controller.rb b/app/controllers/users/applied_transfer_projects_controller.rb
new file mode 100644
index 000000000..74366bb55
--- /dev/null
+++ b/app/controllers/users/applied_transfer_projects_controller.rb
@@ -0,0 +1,41 @@
+class Users::AppliedTransferProjectsController < Users::BaseController
+ before_action :check_auth
+ before_action :find_applied_transfer_project, except: [:index]
+ before_action :find_project, except: [:index]
+
+ def index
+ user_collection_sql = AppliedTransferProject.where(owner_id: @_observed_user.id).to_sql
+ org_collection_sql = AppliedTransferProject.where(owner_id: Organization.joins(team_users: :team).where(team_users: {user_id: @_observed_user.id}, teams: {authorize: %w(admin owner)} )).to_sql
+ @applied_transfer_projects = AppliedTransferProject.from("( #{ user_collection_sql } UNION #{ org_collection_sql } ) AS applied_transfer_projects")
+ @applied_transfer_projects = paginate @applied_transfer_projects
+ end
+
+ # 接受迁移
+ def accept
+ @applied_transfer_project = Projects::AcceptTransferService.call(current_user, @project)
+ rescue Exception => e
+ uid_logger_error(e.message)
+ tip_exception(e.message)
+ end
+
+ # 拒绝迁移
+ def refuse
+ @applied_transfer_project = Projects::RefuseTransferService.call(current_user, @project)
+ rescue Exception => e
+ uid_logger_error(e.message)
+ tip_exception(e.message)
+ end
+
+ private
+ def check_auth
+ return render_forbidden unless observed_logged_user?
+ end
+
+ def find_applied_transfer_project
+ @applied_transfer_project = AppliedTransferProject.find_by_id params[:id]
+ end
+
+ def find_project
+ @project = @applied_transfer_project.project
+ end
+end
\ No newline at end of file
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index 7f49ab614..c6ac626a3 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -27,11 +27,18 @@ class UsersController < ApplicationController
def show
#待办事项,现在未做
- @undo_events = 0
+ if User.current.login == @user.login
+ @waiting_applied_messages = @user.applied_messages.waiting
+ @common_applied_transfer_projects = AppliedTransferProject.where(owner_id: @user.id).common + AppliedTransferProject.where(owner_id: Organization.joins(team_users: :team).where(team_users: {user_id: @user.id}, teams: {authorize: %w(admin owner)} )).common
+ @undo_events = @waiting_applied_messages.size + @common_applied_transfer_projects.size
+ else
+ @undo_events = 0
+ end
#用户的组织数量
# @user_composes_count = @user.composes.size
@user_composes_count = 0
- @user_org_count = User.current.logged? ? @user.organizations.with_visibility(%w(common limited)).size + @user.organizations.with_visibility("privacy").joins(:organization_users).where(organization_users: {user_id: current_user.id}).size : @user.organizations.with_visibility("common").size
+ user_organizations = User.current.logged? ? @user.organizations.with_visibility(%w(common limited)) + @user.organizations.with_visibility("privacy").joins(:team_users).where(team_users: {user_id: current_user.id}) : @user.organizations.with_visibility("common")
+ @user_org_count = user_organizations.size
user_projects = User.current.logged? && (User.current.admin? || User.current.login == @user.login) ? @user.projects : @user.projects.visible
@projects_common_count = user_projects.common.size
@projects_mirrior_count = user_projects.mirror.size
diff --git a/app/jobs/send_transfer_project_applied_message_job.rb b/app/jobs/send_transfer_project_applied_message_job.rb
new file mode 100644
index 000000000..790d1fd5d
--- /dev/null
+++ b/app/jobs/send_transfer_project_applied_message_job.rb
@@ -0,0 +1,34 @@
+class SendTransferProjectAppliedMessageJob < ApplicationJob
+ queue_as :default
+
+ def perform(applied_transfer_project, applied_user, message_status)
+ project = applied_transfer_project.project
+ owner = applied_transfer_project.owner
+ return unless project.present?
+ return unless owner.present?
+ receivers = project.managers + owner.team_users.joins(:team).where(teams: {authorize: %w(owner admin)})
+ receivers.each do |rec|
+ AppliedMessage.create!(user_id: rec.user_id,
+ applied: applied_transfer_project,
+ status: message_status,
+ name: build_name(project.name, owner.real_name, message_status),
+ applied_user_id: applied_user.id,
+ project_id: project.id)
+ end
+ end
+
+ private
+ def build_name(repo_name, owner_name, message_status)
+ case message_status
+ when 'canceled'
+ return "取消转移【#{repo_name}】仓库"
+ when 'common'
+ return "正在将【#{repo_name}】仓库转移给【#{owner_name}】"
+ when 'successed'
+ return "【#{repo_name}】仓库成功转移给【#{owner_name}】"
+ when 'failure'
+ return "【#{repo_name}】仓库转移失败"
+ end
+ ""
+ end
+end
\ No newline at end of file
diff --git a/app/models/applied_message.rb b/app/models/applied_message.rb
index 8098e6e07..b3ebad34e 100644
--- a/app/models/applied_message.rb
+++ b/app/models/applied_message.rb
@@ -19,5 +19,10 @@
class AppliedMessage < ApplicationRecord
belongs_to :user
belongs_to :applied, polymorphic: true
+ belongs_to :project
+ belongs_to :applied_user, class_name: 'User'
+
+ enum viewed: {waiting: 0, viewed: 1}
+ enum status: {canceled: -1, common: 0, successed: 1, failure: 2} # -1 已取消 0 正在操作 1 操作成功 2 操作失败
end
diff --git a/app/models/applied_transfer_project.rb b/app/models/applied_transfer_project.rb
new file mode 100644
index 000000000..d0e0e5c44
--- /dev/null
+++ b/app/models/applied_transfer_project.rb
@@ -0,0 +1,28 @@
+# == Schema Information
+#
+# Table name: applied_transfer_projects
+#
+# id :integer not null, primary key
+# project_id :integer
+# owner_id :integer
+# user_id :integer
+# status :integer default("0")
+# created_at :datetime not null
+# updated_at :datetime not null
+#
+# Indexes
+#
+# index_applied_transfer_projects_on_owner_id (owner_id)
+# index_applied_transfer_projects_on_project_id (project_id)
+# index_applied_transfer_projects_on_user_id (user_id)
+#
+
+class AppliedTransferProject < ApplicationRecord
+ belongs_to :project
+ belongs_to :user # 操作者
+ belongs_to :owner # 接收个人或组织
+
+ has_many :applied_messages, as: :applied, dependent: :destroy
+
+ enum status: {canceled: -1, common: 0, accepted: 1, refused: 2} # -1 已取消 0 待操作 1 已接收 2 已拒绝
+end
diff --git a/app/models/owner.rb b/app/models/owner.rb
index 1d537a1e0..b65ee0544 100644
--- a/app/models/owner.rb
+++ b/app/models/owner.rb
@@ -66,4 +66,6 @@ class Owner < ApplicationRecord
has_many :projects, foreign_key: :user_id, dependent: :destroy
has_many :repositories, foreign_key: :user_id, dependent: :destroy
+ has_many :applied_transfer_projects, dependent: :destroy
+
end
diff --git a/app/models/project.rb b/app/models/project.rb
index da1a8615b..0c30e13fa 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -112,6 +112,7 @@ class Project < ApplicationRecord
has_one :project_detail, dependent: :destroy
has_many :team_projects, dependent: :destroy
has_many :project_units, dependent: :destroy
+ has_one :applied_transfer_project, dependent: :destroy
after_save :check_project_members
scope :project_statics_select, -> {select(:id,:name, :is_public, :identifier, :status, :project_type, :user_id, :forked_count, :visits, :project_category_id, :project_language_id, :license_id, :ignore_id, :watchers_count, :created_on)}
@@ -295,4 +296,7 @@ class Project < ApplicationRecord
update_column(:updated_on, time)
end
+ def is_transfering
+ applied_transfer_project&.common? ? true : false
+ end
end
diff --git a/app/models/user.rb b/app/models/user.rb
index e16e5ca02..e41e47d93 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -147,9 +147,11 @@ class User < Owner
has_many :trail_auth_apply_actions, -> { where(container_type: 'TrialAuthorization') }, class_name: 'ApplyAction'
# has_many :attendances
-
+ has_many :applied_messages, dependent: :destroy
+ has_many :operate_applied_messages, class_name: 'AppliedMessage', dependent: :destroy
# 项目
has_many :applied_projects, dependent: :destroy
+ has_many :operate_applied_transfer_projects, class_name: 'AppliedTransferProject', dependent: :destroy
# 教学案例
# has_many :libraries, dependent: :destroy
diff --git a/app/services/projects/accept_transfer_service.rb b/app/services/projects/accept_transfer_service.rb
new file mode 100644
index 000000000..57cdfd54b
--- /dev/null
+++ b/app/services/projects/accept_transfer_service.rb
@@ -0,0 +1,43 @@
+class Projects::AcceptTransferService < ApplicationService
+ attr_accessor :applied_transfer_project
+ attr_reader :user, :project
+
+ def initialize(user, project)
+ @user = user
+ @project = project
+ @applied_transfer_project = project.applied_transfer_project
+ end
+
+ def call
+ Rails.logger.info("###### Project accept_transfer_service begin ######")
+ ActiveRecord::Base.transaction do
+ validate!
+ update_apply
+ operate_project
+ send_apply_message
+ end
+
+ Rails.logger.info("##### Project accept_transfer_service end ######")
+
+
+ return @applied_transfer_project
+ end
+
+ private
+ def validate!
+ raise Error, '该仓库未在迁移' unless @applied_transfer_project.present? && @project.is_transfering
+ raise Error, '未拥有接受转移权限' unless @user.admin? || @project.is_admin?(@user)
+ end
+
+ def update_apply
+ @applied_transfer_project.update!(status: 'accepted')
+ end
+
+ def operate_project
+ @project = Projects::TransferService.call(@project, @applied_transfer_project.owner)
+ end
+
+ def send_apply_message
+ SendTransferProjectAppliedMessageJob.perform_now(@applied_transfer_project, @user, 'successed')
+ end
+end
\ No newline at end of file
diff --git a/app/services/projects/apply_transfer_service.rb b/app/services/projects/apply_transfer_service.rb
new file mode 100644
index 000000000..1dd9f7f7a
--- /dev/null
+++ b/app/services/projects/apply_transfer_service.rb
@@ -0,0 +1,41 @@
+class Projects::ApplyTransferService < ApplicationService
+ attr_accessor :owner, :applied_transfer_project
+ attr_reader :user, :project, :owner_id
+
+ def initialize(user, project, owner_id)
+ @user = user
+ @project = project
+ @owner_id = owner_id
+ @owner = Owner.find_by_id(owner_id)
+ end
+
+ def call
+ Rails.logger.info("###### Project apply_transfer_service begin ######")
+ validate!
+ create_apply
+ send_apply_message
+ Rails.logger.info("###### Project apply_transfer_service end ######")
+
+ return @applied_transfer_project
+ end
+
+ private
+ def validate!
+ raise Error, '该仓库正在迁移' if @project.is_transfering
+ raise Error, '新拥有者不存在' unless @owner.present?
+ raise Error, '未拥有转移权限' unless is_permit_owner
+ end
+
+ def is_permit_owner
+ return true unless @owner.is_a?(Organization)
+ return @owner.is_owner?(@user)
+ end
+
+ def create_apply
+ @applied_transfer_project = AppliedTransferProject.create!(user_id: user.id, project_id: project.id, owner_id: owner_id)
+ end
+
+ def send_apply_message
+ SendTransferProjectAppliedMessageJob.perform_now(@applied_transfer_project, @user, 'common')
+ end
+end
\ No newline at end of file
diff --git a/app/services/projects/cancel_transfer_service.rb b/app/services/projects/cancel_transfer_service.rb
new file mode 100644
index 000000000..153b24ffb
--- /dev/null
+++ b/app/services/projects/cancel_transfer_service.rb
@@ -0,0 +1,33 @@
+class Projects::CancelTransferService < ApplicationService
+ attr_accessor :applied_transfer_project
+ attr_reader :user, :project
+
+ def initialize(user, project)
+ @user = user
+ @project = project
+ @applied_transfer_project = project.applied_transfer_project
+ end
+
+ def call
+ Rails.logger.info("###### Project cancel_transfer_service begin ######")
+ validate!
+ update_apply
+ send_apply_message
+ Rails.logger.info("###### Project cancel_transfer_service end ######")
+
+ return @applied_transfer_project
+ end
+
+ private
+ def validate!
+ raise Error, '该仓库未在迁移' unless @applied_transfer_project.present? && @project.is_transfering
+ end
+
+ def update_apply
+ @applied_transfer_project.update!(status: 'canceled')
+ end
+
+ def send_apply_message
+ SendTransferProjectAppliedMessageJob.perform_now(@applied_transfer_project, @user, 'canceled')
+ end
+end
\ No newline at end of file
diff --git a/app/services/projects/refuse_transfer_service.rb b/app/services/projects/refuse_transfer_service.rb
new file mode 100644
index 000000000..88d252465
--- /dev/null
+++ b/app/services/projects/refuse_transfer_service.rb
@@ -0,0 +1,33 @@
+class Projects::RefuseTransferService < ApplicationService
+ attr_accessor :applied_transfer_project
+ attr_reader :user, :project
+
+ def initialize(user, project)
+ @user = user
+ @project = project
+ @applied_transfer_project = project.applied_transfer_project
+ end
+
+ def call
+ Rails.logger.info("###### Project refuse_transfer_service begin ######")
+ validate!
+ update_apply
+ send_apply_message
+ Rails.logger.info("###### Project refuse_transfer_service end ######")
+
+ return @applied_transfer_project
+ end
+
+ private
+ def validate!
+ raise Error, '该仓库未在迁移' unless @applied_transfer_project.present? && @project.is_transfering
+ end
+
+ def update_apply
+ @applied_transfer_project.update!(status: 'refused')
+ end
+
+ def send_apply_message
+ SendTransferProjectAppliedMessageJob.perform_now(@applied_transfer_project, @user, 'failure')
+ end
+end
\ No newline at end of file
diff --git a/app/views/organizations/organizations/_simple.json.jbuilder b/app/views/organizations/organizations/_simple.json.jbuilder
new file mode 100644
index 000000000..12792b125
--- /dev/null
+++ b/app/views/organizations/organizations/_simple.json.jbuilder
@@ -0,0 +1,5 @@
+json.id organization.id
+json.name organization.login
+json.nickname organization.nickname.blank? ? organization.name : organization.nickname
+json.description organization.description
+json.avatar_url url_to_avatar(organization)
diff --git a/app/views/projects/applied_transfer_projects/_detail.json.jbuilder b/app/views/projects/applied_transfer_projects/_detail.json.jbuilder
new file mode 100644
index 000000000..e583ed1d1
--- /dev/null
+++ b/app/views/projects/applied_transfer_projects/_detail.json.jbuilder
@@ -0,0 +1,21 @@
+project = object.project
+json.project do
+ json.id project.id
+ json.identifier project.identifier
+ json.name project.name
+ json.description project.description
+ json.is_public project.is_public
+ json.owner do
+ json.partial! "/users/user_simple", locals: {user: project.owner}
+ end
+end
+json.user do
+ json.partial! "/users/user_simple", locals: {user: object.user}
+end
+json.owner do
+ json.partial! "/users/user_simple", locals: {user: object.owner}
+end
+json.id object.id
+json.status object.status
+json.created_at format_time(object.created_at)
+json.time_ago time_from_now(object.created_at)
diff --git a/app/views/projects/applied_transfer_projects/cancel.json.jbuilder b/app/views/projects/applied_transfer_projects/cancel.json.jbuilder
new file mode 100644
index 000000000..59da42d4e
--- /dev/null
+++ b/app/views/projects/applied_transfer_projects/cancel.json.jbuilder
@@ -0,0 +1 @@
+json.partial! "/projects/applied_transfer_projects/detail", locals: {object: @applied_transfer_project}
diff --git a/app/views/projects/applied_transfer_projects/create.json.jbuilder b/app/views/projects/applied_transfer_projects/create.json.jbuilder
new file mode 100644
index 000000000..59da42d4e
--- /dev/null
+++ b/app/views/projects/applied_transfer_projects/create.json.jbuilder
@@ -0,0 +1 @@
+json.partial! "/projects/applied_transfer_projects/detail", locals: {object: @applied_transfer_project}
diff --git a/app/views/projects/applied_transfer_projects/organizations.json.jbuilder b/app/views/projects/applied_transfer_projects/organizations.json.jbuilder
new file mode 100644
index 000000000..772910f0b
--- /dev/null
+++ b/app/views/projects/applied_transfer_projects/organizations.json.jbuilder
@@ -0,0 +1,4 @@
+json.total_count @organizations.size
+json.organizations @organizations do |org|
+ json.partial! "/organizations/organizations/simple", locals: {organization: org}
+end
diff --git a/app/views/repositories/edit.json.jbuilder b/app/views/repositories/edit.json.jbuilder
index 076ac3aa8..d268696cc 100644
--- a/app/views/repositories/edit.json.jbuilder
+++ b/app/views/repositories/edit.json.jbuilder
@@ -7,4 +7,6 @@ json.project_language_id @project.project_language_id
json.private !@project.is_public
json.website @project.website
json.project_units @project.project_units.pluck(:unit_type)
-json.lesson_url @project.lesson_url
\ No newline at end of file
+json.lesson_url @project.lesson_url
+json.permission render_permission(current_user, @project)
+json.is_transfering @project.is_transfering
\ No newline at end of file
diff --git a/app/views/users/_user_simple.json.jbuilder b/app/views/users/_user_simple.json.jbuilder
index 3f9feebbe..cfd06a405 100644
--- a/app/views/users/_user_simple.json.jbuilder
+++ b/app/views/users/_user_simple.json.jbuilder
@@ -1,4 +1,5 @@
json.id user.id
+json.type user.type
json.name user.real_name
json.login user.login
json.image_url url_to_avatar(user)
\ No newline at end of file
diff --git a/app/views/users/applied_messages/_detail.json.jbuilder b/app/views/users/applied_messages/_detail.json.jbuilder
new file mode 100644
index 000000000..0bbd49b01
--- /dev/null
+++ b/app/views/users/applied_messages/_detail.json.jbuilder
@@ -0,0 +1,25 @@
+project = object.project
+json.project do
+ json.id project.id
+ json.identifier project.identifier
+ json.name project.name
+ json.description project.description
+ json.is_public project.is_public
+ json.owner do
+ json.partial! "/users/user_simple", locals: {user: project.owner}
+ end
+end
+json.user do
+ json.partial! "/users/user_simple", locals: {user: object.user}
+end
+json.applied do
+ json.partial! "/projects/applied_transfer_projects/detail", locals: {object: object.applied}
+end
+json.applied_user do
+ json.partial! "/users/user_simple", locals: {user: object.applied_user}
+end
+json.name object.name
+json.viewed object.viewed
+json.status object.status
+json.created_at format_time(object.created_at)
+json.time_ago time_from_now(object.created_at)
diff --git a/app/views/users/applied_messages/index.json.jbuilder b/app/views/users/applied_messages/index.json.jbuilder
new file mode 100644
index 000000000..75647566f
--- /dev/null
+++ b/app/views/users/applied_messages/index.json.jbuilder
@@ -0,0 +1,4 @@
+json.total_count @applied_messages.total_count
+json.applied_messages @applied_messages do |message|
+ json.partial! "/users/applied_messages/detail", locals: {object: message}
+end
diff --git a/app/views/users/applied_transfer_projects/accept.json.jbuilder b/app/views/users/applied_transfer_projects/accept.json.jbuilder
new file mode 100644
index 000000000..59da42d4e
--- /dev/null
+++ b/app/views/users/applied_transfer_projects/accept.json.jbuilder
@@ -0,0 +1 @@
+json.partial! "/projects/applied_transfer_projects/detail", locals: {object: @applied_transfer_project}
diff --git a/app/views/users/applied_transfer_projects/index.json.jbuilder b/app/views/users/applied_transfer_projects/index.json.jbuilder
new file mode 100644
index 000000000..caf9d1ade
--- /dev/null
+++ b/app/views/users/applied_transfer_projects/index.json.jbuilder
@@ -0,0 +1,4 @@
+json.total_count @applied_transfer_projects.total_count
+json.applied_transfer_projects @applied_transfer_projects do |apply|
+ json.partial! "/projects/applied_transfer_projects/detail", locals: {object: apply}
+end
diff --git a/app/views/users/applied_transfer_projects/refuse.json.jbuilder b/app/views/users/applied_transfer_projects/refuse.json.jbuilder
new file mode 100644
index 000000000..59da42d4e
--- /dev/null
+++ b/app/views/users/applied_transfer_projects/refuse.json.jbuilder
@@ -0,0 +1 @@
+json.partial! "/projects/applied_transfer_projects/detail", locals: {object: @applied_transfer_project}
diff --git a/config/routes.rb b/config/routes.rb
index bbcc29231..fa76ba467 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -257,6 +257,13 @@ Rails.application.routes.draw do
end
scope module: :users do
+ resources :applied_messages, only: [:index]
+ resources :applied_transfer_projects, only: [:index] do
+ member do
+ post :accept
+ post :refuse
+ end
+ end
resources :organizations, only: [:index]
# resources :projects, only: [:index]
# resources :subjects, only: [:index]
@@ -532,6 +539,12 @@ Rails.application.routes.draw do
scope module: :projects do
resources :teams, only: [:index, :create, :destroy]
resources :project_units, only: [:index, :create]
+ resources :applied_transfer_projects, only: [:create] do
+ collection do
+ get :organizations
+ post :cancel
+ end
+ end
scope do
get(
'/blob/*id/diff',
diff --git a/db/migrate/20210425032825_create_applied_transfer_projects.rb b/db/migrate/20210425032825_create_applied_transfer_projects.rb
new file mode 100644
index 000000000..5c6774095
--- /dev/null
+++ b/db/migrate/20210425032825_create_applied_transfer_projects.rb
@@ -0,0 +1,12 @@
+class CreateAppliedTransferProjects < ActiveRecord::Migration[5.2]
+ def change
+ create_table :applied_transfer_projects do |t|
+ t.references :project
+ t.references :owner
+ t.references :user
+ t.integer :status, default: 0
+
+ t.timestamps
+ end
+ end
+end
From 8b7b1b7a4e603883af7f83f313a9ebb29204bcac Mon Sep 17 00:00:00 2001
From: "vilet.yy"
Date: Mon, 26 Apr 2021 10:07:22 +0800
Subject: [PATCH 02/12] add: api doc about projects
---
.../applied_transfer_projects_controller.rb | 2 +-
app/docs/slate/source/includes/_projects.md | 238 +++++++++
.../projects/apply_transfer_service.rb | 10 +-
public/docs/api.html | 498 ++++++++++++++++++
4 files changed, 742 insertions(+), 6 deletions(-)
diff --git a/app/controllers/projects/applied_transfer_projects_controller.rb b/app/controllers/projects/applied_transfer_projects_controller.rb
index 887949f8d..ad6c9b19c 100644
--- a/app/controllers/projects/applied_transfer_projects_controller.rb
+++ b/app/controllers/projects/applied_transfer_projects_controller.rb
@@ -6,7 +6,7 @@ class Projects::AppliedTransferProjectsController < Projects::BaseController
end
def create
- @applied_transfer_project = Projects::ApplyTransferService.call(current_user, @project, params[:owner_id])
+ @applied_transfer_project = Projects::ApplyTransferService.call(current_user, @project, params[:owner_name])
rescue Exception => e
uid_logger_error(e.message)
tip_exception(e.message)
diff --git a/app/docs/slate/source/includes/_projects.md b/app/docs/slate/source/includes/_projects.md
index 0a46d8cc7..85359d80e 100644
--- a/app/docs/slate/source/includes/_projects.md
+++ b/app/docs/slate/source/includes/_projects.md
@@ -526,3 +526,241 @@ await octokit.request('POST /api/jaser/jasder_test/forks.json')
"identifier": "newadm"
}
```
+
+## 用户管理的组织列表
+用户管理的组织列表
+
+> 示例:
+
+```shell
+curl -X GET \
+http://localhost:3000/api/ceshi1/ceshi_repo1/applied_transfer_projects/organizations.json | jq
+```
+
+```javascript
+await octokit.request('GET /api/:owner/:repo/applied_transfer_projects/organizations')
+```
+
+### HTTP 请求
+`GET api/:owner/:repo/applied_transfer_projects/organizations`
+
+### 请求参数
+参数 | 必选 | 默认 | 类型 | 字段说明
+--------- | ------- | ------- | -------- | ----------
+owner |是| |string |用户登录名
+repo |是| |string |项目标识identifier
+
+### 返回字段说明
+参数 | 类型 | 字段说明
+--------- | ----------- | -----------
+name |string|组织标识
+nickname |string|组织名称
+description|string|组织描述
+avatar_url|string|组织头像
+
+
+> 返回的JSON示例:
+
+```json
+{
+ "total_count": 3,
+ "organizations": [
+ {
+ "id": 9,
+ "name": "ceshi_org",
+ "nickname": "测试组织",
+ "description": "测试组织",
+ "avatar_url": "images/avatars/Organization/9?t=1612706073"
+ },
+ {
+ "id": 51,
+ "name": "ceshi",
+ "nickname": "测试组织哈哈哈",
+ "description": "23212312",
+ "avatar_url": "images/avatars/Organization/51?t=1618800723"
+ },
+ {
+ "id": 52,
+ "name": "ceshi1",
+ "nickname": "身份卡手动阀",
+ "description": "1231手动阀是的",
+ "avatar_url": "images/avatars/Organization/52?t=1618805056"
+ }
+ ]
+}
+```
+
+## 迁移项目
+迁移项目,edit接口is_transfering为true表示正在迁移
+
+> 示例:
+
+```shell
+curl -X POST http://localhost:3000/api/ceshi1/ceshi_repo1/applied_transfer_projects.json
+```
+
+```javascript
+await octokit.request('POST /api/:owner/:repo/applied_transfer_projects.json')
+```
+
+### HTTP 请求
+`POST /api/:owner/:repo/applied_transfer_projects.json`
+
+### 请求参数
+参数 | 必选 | 默认 | 类型 | 字段说明
+--------- | ------- | ------- | -------- | ----------
+|owner |是| |string |用户登录名 |
+|repo |是| |string |项目标识identifier |
+|owner_name|是| |string |迁移对象标识 |
+
+### 返回字段说明
+参数 | 类型 | 字段说明
+--------- | ----------- | -----------
+|id |int |项目id |
+|status |string |项目迁移状态,canceled:取消,common:正在迁移, accept:已接受,refuse:已拒绝|
+|time_ago |string |项目迁移创建的时间 |
+|project.id |int |迁移项目的id |
+|project.identifier |string |迁移项目的标识 |
+|project.name |string |迁移项目的名称 |
+|project.description |string |迁移项目的描述 |
+|project.is_public |bool |迁移项目是否公开 |
+|project.owner.id |bool |迁移项目拥有者id |
+|project.owner.type |string |迁移项目拥有者类型 |
+|project.owner.name |string |迁移项目拥有者昵称 |
+|project.owner.login |string |迁移项目拥有者标识 |
+|project.owner.image_url |string |迁移项目拥有者头像 |
+|user.id |int |迁移创建者的id |
+|user.type |string |迁移创建者的类型 |
+|user.name |string |迁移创建者的名称 |
+|user.login |string |迁移创建者的标识 |
+|user.image_url |string |迁移创建者头像 |
+|owner.id |int |迁移接受者的id |
+|owner.type |string |迁移接受者的类型 |
+|owner.name |string |迁移接受者的名称 |
+|owner.login |string |迁移接受者的标识 |
+|owner.image_url |string |迁移接受者头像 |
+> 返回的JSON示例:
+
+```json
+{
+ "project": {
+ "id": 86,
+ "identifier": "ceshi_repo1",
+ "name": "测试项目啊1",
+ "description": "二十多",
+ "is_public": true,
+ "owner": {
+ "id": 52,
+ "type": "Organization",
+ "name": "身份卡手动阀",
+ "login": "ceshi1",
+ "image_url": "images/avatars/Organization/52?t=1618805056"
+ }
+ },
+ "user": {
+ "id": 6,
+ "type": "User",
+ "name": "yystopf",
+ "login": "yystopf",
+ "image_url": "system/lets/letter_avatars/2/Y/241_125_89/120.png"
+ },
+ "owner": {
+ "id": 9,
+ "type": "Organization",
+ "name": "测试组织",
+ "login": "ceshi_org",
+ "image_url": "images/avatars/Organization/9?t=1612706073"
+ },
+ "id": 4,
+ "status": "common",
+ "created_at": "2021-04-26 09:54",
+ "time_ago": "1分钟前"
+}
+```
+
+## 取消迁移项目
+迁移项目,edit接口is_transfering为true表示正在迁移
+
+> 示例:
+
+```shell
+curl -X POST http://localhost:3000/api/ceshi1/ceshi_repo1/applied_transfer_projects/cancel.json
+```
+
+```javascript
+await octokit.request('POST /api/:owner/:repo/applied_transfer_projects/cancel.json')
+```
+
+### HTTP 请求
+`POST /api/:owner/:repo/applied_transfer_projects/cancel.json`
+
+### 请求参数
+参数 | 必选 | 默认 | 类型 | 字段说明
+--------- | ------- | ------- | -------- | ----------
+|owner |是| |string |用户登录名 |
+|repo |是| |string |项目标识identifier |
+
+### 返回字段说明
+参数 | 类型 | 字段说明
+--------- | ----------- | -----------
+|id |int |项目id |
+|status |string |项目迁移状态,canceled:取消,common:正在迁移, accept:已接受,refuse:已拒绝|
+|time_ago |string |项目迁移创建的时间 |
+|project.id |int |迁移项目的id |
+|project.identifier |string |迁移项目的标识 |
+|project.name |string |迁移项目的名称 |
+|project.description |string |迁移项目的描述 |
+|project.is_public |bool |迁移项目是否公开 |
+|project.owner.id |bool |迁移项目拥有者id |
+|project.owner.type |string |迁移项目拥有者类型 |
+|project.owner.name |string |迁移项目拥有者昵称 |
+|project.owner.login |string |迁移项目拥有者标识 |
+|project.owner.image_url |string |迁移项目拥有者头像 |
+|user.id |int |迁移创建者的id |
+|user.type |string |迁移创建者的类型 |
+|user.name |string |迁移创建者的名称 |
+|user.login |string |迁移创建者的标识 |
+|user.image_url |string |迁移创建者头像 |
+|owner.id |int |迁移接受者的id |
+|owner.type |string |迁移接受者的类型 |
+|owner.name |string |迁移接受者的名称 |
+|owner.login |string |迁移接受者的标识 |
+|owner.image_url |string |迁移接受者头像 |
+> 返回的JSON示例:
+
+```json
+{
+ "project": {
+ "id": 86,
+ "identifier": "ceshi_repo1",
+ "name": "测试项目啊1",
+ "description": "二十多",
+ "is_public": true,
+ "owner": {
+ "id": 52,
+ "type": "Organization",
+ "name": "身份卡手动阀",
+ "login": "ceshi1",
+ "image_url": "images/avatars/Organization/52?t=1618805056"
+ }
+ },
+ "user": {
+ "id": 6,
+ "type": "User",
+ "name": "yystopf",
+ "login": "yystopf",
+ "image_url": "system/lets/letter_avatars/2/Y/241_125_89/120.png"
+ },
+ "owner": {
+ "id": 9,
+ "type": "Organization",
+ "name": "测试组织",
+ "login": "ceshi_org",
+ "image_url": "images/avatars/Organization/9?t=1612706073"
+ },
+ "id": 4,
+ "status": "common",
+ "created_at": "2021-04-26 09:54",
+ "time_ago": "1分钟前"
+}
+```
\ No newline at end of file
diff --git a/app/services/projects/apply_transfer_service.rb b/app/services/projects/apply_transfer_service.rb
index 1dd9f7f7a..ee4ec4265 100644
--- a/app/services/projects/apply_transfer_service.rb
+++ b/app/services/projects/apply_transfer_service.rb
@@ -1,12 +1,12 @@
class Projects::ApplyTransferService < ApplicationService
attr_accessor :owner, :applied_transfer_project
- attr_reader :user, :project, :owner_id
+ attr_reader :user, :project, :owner_name
- def initialize(user, project, owner_id)
+ def initialize(user, project, owner_name)
@user = user
@project = project
- @owner_id = owner_id
- @owner = Owner.find_by_id(owner_id)
+ @owner_name = owner_name
+ @owner = Owner.find_by(login: owner_name)
end
def call
@@ -32,7 +32,7 @@ class Projects::ApplyTransferService < ApplicationService
end
def create_apply
- @applied_transfer_project = AppliedTransferProject.create!(user_id: user.id, project_id: project.id, owner_id: owner_id)
+ @applied_transfer_project = AppliedTransferProject.create!(user_id: user.id, project_id: project.id, owner_id: @owner.id)
end
def send_apply_message
diff --git a/public/docs/api.html b/public/docs/api.html
index 1b75a97a2..a2e4ef957 100644
--- a/public/docs/api.html
+++ b/public/docs/api.html
@@ -366,6 +366,15 @@
Fork项目
+
+ 用户管理的组织列表
+
+
+ 迁移项目
+
+
+ 取消迁移项目
+
@@ -1590,6 +1599,495 @@ http://localhost:3000/api/projects/migrate.json
"id": 3290,
"identifier": "newadm"
}
+用户管理的组织列表
+用户管理的组织列表
+
+
+示例:
+
+curl -X GET \
+http://localhost:3000/api/ceshi1/ceshi_repo1/applied_transfer_projects/organizations.json | jq
+
await octokit.request('GET /api/:owner/:repo/applied_transfer_projects/organizations')
+
HTTP 请求
+GET api/:owner/:repo/applied_transfer_projects/organizations
+请求参数
+
+
+| 参数 |
+必选 |
+默认 |
+类型 |
+字段说明 |
+
+
+
+| owner |
+是 |
+ |
+string |
+用户登录名 |
+
+
+| repo |
+是 |
+ |
+string |
+项目标识identifier |
+
+
+返回字段说明
+
+
+| 参数 |
+类型 |
+字段说明 |
+
+
+
+| name |
+string |
+组织标识 |
+
+
+| nickname |
+string |
+组织名称 |
+
+
+
+description|string|组织描述
+avatar_url|string|组织头像
+
+
+返回的JSON示例:
+
+{
+ "total_count": 3,
+ "organizations": [
+ {
+ "id": 9,
+ "name": "ceshi_org",
+ "nickname": "测试组织",
+ "description": "测试组织",
+ "avatar_url": "images/avatars/Organization/9?t=1612706073"
+ },
+ {
+ "id": 51,
+ "name": "ceshi",
+ "nickname": "测试组织哈哈哈",
+ "description": "23212312",
+ "avatar_url": "images/avatars/Organization/51?t=1618800723"
+ },
+ {
+ "id": 52,
+ "name": "ceshi1",
+ "nickname": "身份卡手动阀",
+ "description": "1231手动阀是的",
+ "avatar_url": "images/avatars/Organization/52?t=1618805056"
+ }
+ ]
+}
+
迁移项目
+迁移项目,edit接口is_transfering为true表示正在迁移
+
+
+示例:
+
+curl -X POST http://localhost:3000/api/ceshi1/ceshi_repo1/applied_transfer_projects.json
+
await octokit.request('POST /api/:owner/:repo/applied_transfer_projects.json')
+
HTTP 请求
+POST /api/:owner/:repo/applied_transfer_projects.json
+请求参数
+
+
+| 参数 |
+必选 |
+默认 |
+类型 |
+字段说明 |
+
+
+
+| owner |
+是 |
+ |
+string |
+用户登录名 |
+
+
+| repo |
+是 |
+ |
+string |
+项目标识identifier |
+
+
+| owner_name |
+是 |
+ |
+string |
+迁移对象标识 |
+
+
+返回字段说明
+
+
+| 参数 |
+类型 |
+字段说明 |
+
+
+
+| id |
+int |
+项目id |
+
+
+| status |
+string |
+项目迁移状态,canceled:取消,common:正在迁移, accept:已接受,refuse:已拒绝 |
+
+
+| time_ago |
+string |
+项目迁移创建的时间 |
+
+
+| project.id |
+int |
+迁移项目的id |
+
+
+| project.identifier |
+string |
+迁移项目的标识 |
+
+
+| project.name |
+string |
+迁移项目的名称 |
+
+
+| project.description |
+string |
+迁移项目的描述 |
+
+
+| project.is_public |
+bool |
+迁移项目是否公开 |
+
+
+| project.owner.id |
+bool |
+迁移项目拥有者id |
+
+
+| project.owner.type |
+string |
+迁移项目拥有者类型 |
+
+
+| project.owner.name |
+string |
+迁移项目拥有者昵称 |
+
+
+| project.owner.login |
+string |
+迁移项目拥有者标识 |
+
+
+| project.owner.image_url |
+string |
+迁移项目拥有者头像 |
+
+
+| user.id |
+int |
+迁移创建者的id |
+
+
+| user.type |
+string |
+迁移创建者的类型 |
+
+
+| user.name |
+string |
+迁移创建者的名称 |
+
+
+| user.login |
+string |
+迁移创建者的标识 |
+
+
+| user.image_url |
+string |
+迁移创建者头像 |
+
+
+| owner.id |
+int |
+迁移接受者的id |
+
+
+| owner.type |
+string |
+迁移接受者的类型 |
+
+
+| owner.name |
+string |
+迁移接受者的名称 |
+
+
+| owner.login |
+string |
+迁移接受者的标识 |
+
+
+| owner.image_url |
+string |
+迁移接受者头像 |
+
+
+
+
+返回的JSON示例:
+
+{
+ "project": {
+ "id": 86,
+ "identifier": "ceshi_repo1",
+ "name": "测试项目啊1",
+ "description": "二十多",
+ "is_public": true,
+ "owner": {
+ "id": 52,
+ "type": "Organization",
+ "name": "身份卡手动阀",
+ "login": "ceshi1",
+ "image_url": "images/avatars/Organization/52?t=1618805056"
+ }
+ },
+ "user": {
+ "id": 6,
+ "type": "User",
+ "name": "yystopf",
+ "login": "yystopf",
+ "image_url": "system/lets/letter_avatars/2/Y/241_125_89/120.png"
+ },
+ "owner": {
+ "id": 9,
+ "type": "Organization",
+ "name": "测试组织",
+ "login": "ceshi_org",
+ "image_url": "images/avatars/Organization/9?t=1612706073"
+ },
+ "id": 4,
+ "status": "common",
+ "created_at": "2021-04-26 09:54",
+ "time_ago": "1分钟前"
+}
+
取消迁移项目
+迁移项目,edit接口is_transfering为true表示正在迁移
+
+
+示例:
+
+curl -X POST http://localhost:3000/api/ceshi1/ceshi_repo1/applied_transfer_projects/cancel.json
+
await octokit.request('POST /api/:owner/:repo/applied_transfer_projects/cancel.json')
+
HTTP 请求
+POST /api/:owner/:repo/applied_transfer_projects/cancel.json
+请求参数
+
+
+| 参数 |
+必选 |
+默认 |
+类型 |
+字段说明 |
+
+
+
+| owner |
+是 |
+ |
+string |
+用户登录名 |
+
+
+| repo |
+是 |
+ |
+string |
+项目标识identifier |
+
+
+返回字段说明
+
+
+| 参数 |
+类型 |
+字段说明 |
+
+
+
+| id |
+int |
+项目id |
+
+
+| status |
+string |
+项目迁移状态,canceled:取消,common:正在迁移, accept:已接受,refuse:已拒绝 |
+
+
+| time_ago |
+string |
+项目迁移创建的时间 |
+
+
+| project.id |
+int |
+迁移项目的id |
+
+
+| project.identifier |
+string |
+迁移项目的标识 |
+
+
+| project.name |
+string |
+迁移项目的名称 |
+
+
+| project.description |
+string |
+迁移项目的描述 |
+
+
+| project.is_public |
+bool |
+迁移项目是否公开 |
+
+
+| project.owner.id |
+bool |
+迁移项目拥有者id |
+
+
+| project.owner.type |
+string |
+迁移项目拥有者类型 |
+
+
+| project.owner.name |
+string |
+迁移项目拥有者昵称 |
+
+
+| project.owner.login |
+string |
+迁移项目拥有者标识 |
+
+
+| project.owner.image_url |
+string |
+迁移项目拥有者头像 |
+
+
+| user.id |
+int |
+迁移创建者的id |
+
+
+| user.type |
+string |
+迁移创建者的类型 |
+
+
+| user.name |
+string |
+迁移创建者的名称 |
+
+
+| user.login |
+string |
+迁移创建者的标识 |
+
+
+| user.image_url |
+string |
+迁移创建者头像 |
+
+
+| owner.id |
+int |
+迁移接受者的id |
+
+
+| owner.type |
+string |
+迁移接受者的类型 |
+
+
+| owner.name |
+string |
+迁移接受者的名称 |
+
+
+| owner.login |
+string |
+迁移接受者的标识 |
+
+
+| owner.image_url |
+string |
+迁移接受者头像 |
+
+
+
+
+返回的JSON示例:
+
+{
+ "project": {
+ "id": 86,
+ "identifier": "ceshi_repo1",
+ "name": "测试项目啊1",
+ "description": "二十多",
+ "is_public": true,
+ "owner": {
+ "id": 52,
+ "type": "Organization",
+ "name": "身份卡手动阀",
+ "login": "ceshi1",
+ "image_url": "images/avatars/Organization/52?t=1618805056"
+ }
+ },
+ "user": {
+ "id": 6,
+ "type": "User",
+ "name": "yystopf",
+ "login": "yystopf",
+ "image_url": "system/lets/letter_avatars/2/Y/241_125_89/120.png"
+ },
+ "owner": {
+ "id": 9,
+ "type": "Organization",
+ "name": "测试组织",
+ "login": "ceshi_org",
+ "image_url": "images/avatars/Organization/9?t=1612706073"
+ },
+ "id": 4,
+ "status": "common",
+ "created_at": "2021-04-26 09:54",
+ "time_ago": "1分钟前"
+}
Repositories
仓库详情
仓库详情
From d532dc7cf55b9819853adc9aeb4937b2a6422fb6 Mon Sep 17 00:00:00 2001
From: "vilet.yy"
Date: Mon, 26 Apr 2021 10:57:57 +0800
Subject: [PATCH 03/12] fix: some bug and users api doc
---
app/docs/slate/source/includes/_projects.md | 8 +-
app/docs/slate/source/includes/_users.md | 393 +++++++
...nd_transfer_project_applied_message_job.rb | 6 +-
.../projects/apply_transfer_service.rb | 9 +-
.../applied_messages/_detail.json.jbuilder | 29 +-
public/docs/api.html | 1042 +++++++++++++++--
6 files changed, 1361 insertions(+), 126 deletions(-)
diff --git a/app/docs/slate/source/includes/_projects.md b/app/docs/slate/source/includes/_projects.md
index 85359d80e..87a37c45b 100644
--- a/app/docs/slate/source/includes/_projects.md
+++ b/app/docs/slate/source/includes/_projects.md
@@ -555,7 +555,7 @@ repo |是| |string |项目标识identifier
--------- | ----------- | -----------
name |string|组织标识
nickname |string|组织名称
-description|string|组织描述
+description|string|组织描述
avatar_url|string|组织头像
@@ -703,9 +703,9 @@ await octokit.request('POST /api/:owner/:repo/applied_transfer_projects/cancel.j
### 返回字段说明
参数 | 类型 | 字段说明
--------- | ----------- | -----------
-|id |int |项目id |
-|status |string |项目迁移状态,canceled:取消,common:正在迁移, accept:已接受,refuse:已拒绝|
-|time_ago |string |项目迁移创建的时间 |
+|id |int |迁移id |
+|status |string |迁移状态,canceled:取消,common:正在迁移, accept:已接受,refuse:已拒绝|
+|time_ago |string |迁移创建的时间 |
|project.id |int |迁移项目的id |
|project.identifier |string |迁移项目的标识 |
|project.name |string |迁移项目的名称 |
diff --git a/app/docs/slate/source/includes/_users.md b/app/docs/slate/source/includes/_users.md
index 62a6391e1..1d1afc028 100644
--- a/app/docs/slate/source/includes/_users.md
+++ b/app/docs/slate/source/includes/_users.md
@@ -1,3 +1,9 @@
+
# Users
## 获取当前登陆用户信息
@@ -40,3 +46,390 @@ await octokit.request('GET /api/users/me.json')
+
+## 待办事项-用户通知信息
+待办事项-用户通知信息
+
+> 示例:
+
+```shell
+curl -X GET http://localhost:3000/api/users/yystopf/applied_messages.json
+```
+
+```javascript
+await octokit.request('GET /api/users/:login/applied_messages.json')
+```
+
+### HTTP 请求
+`GET /api/users/:login/applied_messages.json`
+
+### 请求字段说明:
+参数 | 类型 | 字段说明
+--------- | ----------- | -----------
+|login |string |用户标识 |
+
+### 返回字段说明:
+参数 | 类型 | 字段说明
+--------- | ----------- | -----------
+|applied |object |通知主体 |
+|applied.id |int |通知主体的迁移id |
+|applied.status |string |通知主体的迁移状态,canceled:取消,common:正在迁移, accept:已接受,refuse:已拒绝|
+|applied.time_ago |string |通知主体的迁移创建的时间 |
+|applied.project.id |int |通知主体的迁移项目的id |
+|applied.project.identifier |string |通知主体的迁移项目的标识 |
+|applied.project.name |string |通知主体的迁移项目的名称 |
+|applied.project.description |string |通知主体的迁移项目的描述 |
+|applied.project.is_public |bool |通知主体的迁移项目是否公开 |
+|applied.project.owner.id |bool |通知主体的迁移项目拥有者id |
+|applied.project.owner.type |string |通知主体的迁移项目拥有者类型 |
+|applied.project.owner.name |string |通知主体的迁移项目拥有者昵称 |
+|applied.project.owner.login |string |通知主体的迁移项目拥有者标识 |
+|applied.project.owner.image_url |string |通知主体的迁移项目拥有者头像 |
+|applied.user.id |int |通知主体的迁移创建者的id |
+|applied.user.type |string |通知主体的迁移创建者的类型 |
+|applied.user.name |string |通知主体的迁移创建者的名称 |
+|applied.user.login |string |通知主体的迁移创建者的标识 |
+|applied.user.image_url |string |通知主体的迁移创建者头像 |
+|applied.owner.id |int |通知主体的迁移接受者的id |
+|applied.owner.type |string |通知主体的迁移接受者的类型 |
+|applied.owner.name |string |通知主体的迁移接受者的名称 |
+|applied.owner.login |string |通知主体的迁移接受者的标识 |
+|applied.owner.image_url |string |通知主体的迁移接受者头像 |
+|applied_type |string |通知类型 |
+|name |string | 通知内容 |
+|viewed |string|是否已读,waiting:未读,viewed:已读|
+|status |string|通知状态, canceled:已取消,common: 正常,successed:成功,failure:失败|
+|time_ago |string|通知时间|
+
+
+> 返回的JSON示例:
+
+```json
+{
+ "total_count": 5,
+ "applied_messages": [
+ {
+ "applied": {
+ "project": {
+ "id": 86,
+ "identifier": "ceshi_repo1",
+ "name": "测试项目啊1",
+ "description": "二十多",
+ "is_public": true,
+ "owner": {
+ "id": 52,
+ "type": "Organization",
+ "name": "身份卡手动阀",
+ "login": "ceshi1",
+ "image_url": "images/avatars/Organization/52?t=1618805056"
+ }
+ },
+ "user": {
+ "id": 6,
+ "type": "User",
+ "name": "yystopf",
+ "login": "yystopf",
+ "image_url": "system/lets/letter_avatars/2/Y/241_125_89/120.png"
+ },
+ "owner": {
+ "id": 9,
+ "type": "Organization",
+ "name": "测试组织",
+ "login": "ceshi_org",
+ "image_url": "images/avatars/Organization/9?t=1612706073"
+ },
+ "id": 4,
+ "status": "common",
+ "created_at": "2021-04-26 09:54",
+ "time_ago": "35分钟前"
+ },
+ "applied_user": {
+ "id": 6,
+ "type": "User",
+ "name": "yystopf",
+ "login": "yystopf",
+ "image_url": "system/lets/letter_avatars/2/Y/241_125_89/120.png"
+ },
+ "applied_type": "AppliedTransferProject",
+ "name": "正在将【测试项目啊1】仓库转移给【测试组织】",
+ "viewed": "viewed",
+ "status": "common",
+ "created_at": "2021-04-26 09:54",
+ "time_ago": "35分钟前"
+ },
+ ...
+ ]
+}
+```
+
+## 待办事项-接受仓库
+待办事项-接受仓库
+
+> 示例:
+
+```shell
+curl -X GET http://localhost:3000/api/users/yystopf/applied_transfer_projects.json
+```
+
+```javascript
+await octokit.request('GET /api/users/:login/applied_transfer_projects.json')
+```
+
+### HTTP 请求
+`GET /api/users/:login/applied_transfer_projects.json`
+
+### 请求字段说明:
+参数 | 类型 | 字段说明
+--------- | ----------- | -----------
+|login |string |用户标识 |
+
+### 返回字段说明:
+参数 | 类型 | 字段说明
+--------- | ----------- | -----------
+|id |int |迁移id |
+|status |string |迁移状态,canceled:取消,common:正在迁移, accept:已接受,refuse:已拒绝|
+|time_ago |string |迁移创建的时间 |
+|project.id |int |迁移项目的id |
+|project.identifier |string |迁移项目的标识 |
+|project.name |string |迁移项目的名称 |
+|project.description |string |迁移项目的描述 |
+|project.is_public |bool |迁移项目是否公开 |
+|project.owner.id |bool |迁移项目拥有者id |
+|project.owner.type |string |迁移项目拥有者类型 |
+|project.owner.name |string |迁移项目拥有者昵称 |
+|project.owner.login |string |迁移项目拥有者标识 |
+|project.owner.image_url |string |迁移项目拥有者头像 |
+|user.id |int |迁移创建者的id |
+|user.type |string |迁移创建者的类型 |
+|user.name |string |迁移创建者的名称 |
+|user.login |string |迁移创建者的标识 |
+|user.image_url |string |迁移创建者头像 |
+|owner.id |int |迁移接受者的id |
+|owner.type |string |迁移接受者的类型 |
+|owner.name |string |迁移接受者的名称 |
+|owner.login |string |迁移接受者的标识 |
+|owner.image_url |string |迁移接受者头像 |
+
+
+> 返回的JSON示例:
+
+```json
+{
+ "total_count": 4,
+ "applied_transfer_projects": [
+ {
+ "project": {
+ "id": 86,
+ "identifier": "ceshi_repo1",
+ "name": "测试项目啊1",
+ "description": "二十多",
+ "is_public": true,
+ "owner": {
+ "id": 52,
+ "type": "Organization",
+ "name": "身份卡手动阀",
+ "login": "ceshi1",
+ "image_url": "images/avatars/Organization/52?t=1618805056"
+ }
+ },
+ "user": {
+ "id": 6,
+ "type": "User",
+ "name": "yystopf",
+ "login": "yystopf",
+ "image_url": "system/lets/letter_avatars/2/Y/241_125_89/120.png"
+ },
+ "owner": {
+ "id": 52,
+ "type": "Organization",
+ "name": "身份卡手动阀",
+ "login": "ceshi1",
+ "image_url": "images/avatars/Organization/52?t=1618805056"
+ },
+ "id": 1,
+ "status": "canceled",
+ "created_at": "2021-04-25 18:06",
+ "time_ago": "16小时前"
+ },
+ ...
+ ]
+}
+```
+
+## 用户接受迁移
+用户接受迁移
+
+> 示例:
+
+```shell
+curl -X POST http://localhost:3000/api/users/yystopf/applied_transfer_projects/2/accept.json
+```
+
+```javascript
+await octokit.request('GET /api/users/:login/applied_transfer_projects/:id/accept.json')
+```
+
+### HTTP 请求
+`GET /api/users/:login/applied_transfer_projects/:id/accept.json`
+
+### 请求字段说明:
+参数 | 类型 | 字段说明
+--------- | ----------- | -----------
+|login |string |用户标识 |
+|id |int |迁移id |
+
+### 返回字段说明:
+参数 | 类型 | 字段说明
+--------- | ----------- | -----------
+|id |int |迁移id |
+|status |string |迁移状态,canceled:取消,common:正在迁移, accept:已接受,refuse:已拒绝|
+|time_ago |string |迁移创建的时间 |
+|project.id |int |迁移项目的id |
+|project.identifier |string |迁移项目的标识 |
+|project.name |string |迁移项目的名称 |
+|project.description |string |迁移项目的描述 |
+|project.is_public |bool |迁移项目是否公开 |
+|project.owner.id |bool |迁移项目拥有者id |
+|project.owner.type |string |迁移项目拥有者类型 |
+|project.owner.name |string |迁移项目拥有者昵称 |
+|project.owner.login |string |迁移项目拥有者标识 |
+|project.owner.image_url |string |迁移项目拥有者头像 |
+|user.id |int |迁移创建者的id |
+|user.type |string |迁移创建者的类型 |
+|user.name |string |迁移创建者的名称 |
+|user.login |string |迁移创建者的标识 |
+|user.image_url |string |迁移创建者头像 |
+|owner.id |int |迁移接受者的id |
+|owner.type |string |迁移接受者的类型 |
+|owner.name |string |迁移接受者的名称 |
+|owner.login |string |迁移接受者的标识 |
+|owner.image_url |string |迁移接受者头像 |
+
+
+> 返回的JSON示例:
+
+```json
+{
+ "project": {
+ "id": 86,
+ "identifier": "ceshi_repo1",
+ "name": "测试项目啊1",
+ "description": "二十多",
+ "is_public": true,
+ "owner": {
+ "id": 52,
+ "type": "Organization",
+ "name": "身份卡手动阀",
+ "login": "ceshi1",
+ "image_url": "images/avatars/Organization/52?t=1618805056"
+ }
+ },
+ "user": {
+ "id": 6,
+ "type": "User",
+ "name": "yystopf",
+ "login": "yystopf",
+ "image_url": "system/lets/letter_avatars/2/Y/241_125_89/120.png"
+ },
+ "owner": {
+ "id": 52,
+ "type": "Organization",
+ "name": "身份卡手动阀",
+ "login": "ceshi1",
+ "image_url": "images/avatars/Organization/52?t=1618805056"
+ },
+ "id": 1,
+ "status": "canceled",
+ "created_at": "2021-04-25 18:06",
+ "time_ago": "16小时前"
+}
+```
+
+## 用户拒绝迁移
+用户拒绝迁移
+
+> 示例:
+
+```shell
+curl -X POST http://localhost:3000/api/users/yystopf/applied_transfer_projects/2/refuse.json
+```
+
+```javascript
+await octokit.request('GET /api/users/:login/applied_transfer_projects/:id/refuse.json')
+```
+
+### HTTP 请求
+`GET /api/users/:login/applied_transfer_projects/:id/refuse.json`
+
+### 请求字段说明:
+参数 | 类型 | 字段说明
+--------- | ----------- | -----------
+|login |string |用户标识 |
+|id |int |迁移id |
+
+### 返回字段说明:
+参数 | 类型 | 字段说明
+--------- | ----------- | -----------
+|id |int |迁移id |
+|status |string |迁移状态,canceled:取消,common:正在迁移, accept:已接受,refuse:已拒绝|
+|time_ago |string |迁移创建的时间 |
+|project.id |int |迁移项目的id |
+|project.identifier |string |迁移项目的标识 |
+|project.name |string |迁移项目的名称 |
+|project.description |string |迁移项目的描述 |
+|project.is_public |bool |迁移项目是否公开 |
+|project.owner.id |bool |迁移项目拥有者id |
+|project.owner.type |string |迁移项目拥有者类型 |
+|project.owner.name |string |迁移项目拥有者昵称 |
+|project.owner.login |string |迁移项目拥有者标识 |
+|project.owner.image_url |string |迁移项目拥有者头像 |
+|user.id |int |迁移创建者的id |
+|user.type |string |迁移创建者的类型 |
+|user.name |string |迁移创建者的名称 |
+|user.login |string |迁移创建者的标识 |
+|user.image_url |string |迁移创建者头像 |
+|owner.id |int |迁移接受者的id |
+|owner.type |string |迁移接受者的类型 |
+|owner.name |string |迁移接受者的名称 |
+|owner.login |string |迁移接受者的标识 |
+|owner.image_url |string |迁移接受者头像 |
+
+
+> 返回的JSON示例:
+
+```json
+{
+ "project": {
+ "id": 86,
+ "identifier": "ceshi_repo1",
+ "name": "测试项目啊1",
+ "description": "二十多",
+ "is_public": true,
+ "owner": {
+ "id": 52,
+ "type": "Organization",
+ "name": "身份卡手动阀",
+ "login": "ceshi1",
+ "image_url": "images/avatars/Organization/52?t=1618805056"
+ }
+ },
+ "user": {
+ "id": 6,
+ "type": "User",
+ "name": "yystopf",
+ "login": "yystopf",
+ "image_url": "system/lets/letter_avatars/2/Y/241_125_89/120.png"
+ },
+ "owner": {
+ "id": 52,
+ "type": "Organization",
+ "name": "身份卡手动阀",
+ "login": "ceshi1",
+ "image_url": "images/avatars/Organization/52?t=1618805056"
+ },
+ "id": 1,
+ "status": "canceled",
+ "created_at": "2021-04-25 18:06",
+ "time_ago": "16小时前"
+}
+```
\ No newline at end of file
diff --git a/app/jobs/send_transfer_project_applied_message_job.rb b/app/jobs/send_transfer_project_applied_message_job.rb
index 790d1fd5d..ef05f266d 100644
--- a/app/jobs/send_transfer_project_applied_message_job.rb
+++ b/app/jobs/send_transfer_project_applied_message_job.rb
@@ -6,7 +6,11 @@ class SendTransferProjectAppliedMessageJob < ApplicationJob
owner = applied_transfer_project.owner
return unless project.present?
return unless owner.present?
- receivers = project.managers + owner.team_users.joins(:team).where(teams: {authorize: %w(owner admin)})
+ if owner.is_a?(Organization)
+ receivers = project.managers + owner.team_users.joins(:team).where(teams: {authorize: %w(owner admin)})
+ else
+ receivers = project.managers
+ end
receivers.each do |rec|
AppliedMessage.create!(user_id: rec.user_id,
applied: applied_transfer_project,
diff --git a/app/services/projects/apply_transfer_service.rb b/app/services/projects/apply_transfer_service.rb
index ee4ec4265..7f33cc101 100644
--- a/app/services/projects/apply_transfer_service.rb
+++ b/app/services/projects/apply_transfer_service.rb
@@ -1,12 +1,12 @@
class Projects::ApplyTransferService < ApplicationService
attr_accessor :owner, :applied_transfer_project
- attr_reader :user, :project, :owner_name
+ attr_reader :user, :project, :params
- def initialize(user, project, owner_name)
+ def initialize(user, project, params)
@user = user
@project = project
- @owner_name = owner_name
- @owner = Owner.find_by(login: owner_name)
+ @params = params
+ @owner = Owner.find_by(login: params[:owner_name])
end
def call
@@ -21,6 +21,7 @@ class Projects::ApplyTransferService < ApplicationService
private
def validate!
+ raise Error, '仓库标识不正确' if @project.identifier != params[:identifier]
raise Error, '该仓库正在迁移' if @project.is_transfering
raise Error, '新拥有者不存在' unless @owner.present?
raise Error, '未拥有转移权限' unless is_permit_owner
diff --git a/app/views/users/applied_messages/_detail.json.jbuilder b/app/views/users/applied_messages/_detail.json.jbuilder
index 0bbd49b01..cca202c10 100644
--- a/app/views/users/applied_messages/_detail.json.jbuilder
+++ b/app/views/users/applied_messages/_detail.json.jbuilder
@@ -1,23 +1,24 @@
-project = object.project
-json.project do
- json.id project.id
- json.identifier project.identifier
- json.name project.name
- json.description project.description
- json.is_public project.is_public
- json.owner do
- json.partial! "/users/user_simple", locals: {user: project.owner}
- end
-end
-json.user do
- json.partial! "/users/user_simple", locals: {user: object.user}
-end
+# project = object.project
+# json.project do
+# json.id project.id
+# json.identifier project.identifier
+# json.name project.name
+# json.description project.description
+# json.is_public project.is_public
+# json.owner do
+# json.partial! "/users/user_simple", locals: {user: project.owner}
+# end
+# end
+# json.user do
+# json.partial! "/users/user_simple", locals: {user: object.user}
+# end
json.applied do
json.partial! "/projects/applied_transfer_projects/detail", locals: {object: object.applied}
end
json.applied_user do
json.partial! "/users/user_simple", locals: {user: object.applied_user}
end
+json.applied_type object.applied_type
json.name object.name
json.viewed object.viewed
json.status object.status
diff --git a/public/docs/api.html b/public/docs/api.html
index a2e4ef957..f970ea84d 100644
--- a/public/docs/api.html
+++ b/public/docs/api.html
@@ -331,6 +331,18 @@
获取当前登陆用户信息
+
+ 待办事项-用户通知信息
+
+
+ 待办事项-接受仓库
+
+
+ 用户接受迁移
+
+
+ 用户拒绝迁移
+
@@ -471,73 +483,822 @@ http://localhost:3000/api/licenses
Type |
Description |
-
+
+
+| name |
+false |
+string |
+name of the license |
+
+
+
+
+返回字段说明:
+
+{
+ "licenses": [
+ {
+ "id": 57,
+ "name": "AFL-1.2"
+ },
+ {
+ "id": 76,
+ "name": "AFL-3.0"
+ },
+ {
+ "id": 214,
+ "name": "AFL-1.1"
+ },
+ {
+ "id": 326,
+ "name": "AFL-2.1"
+ },
+ {
+ "id": 350,
+ "name": "AFL-2.0"
+ }
+ ]
+}
+
Gitignores
gitignore模板列表
+获取gitignore模板列表, 支持名称搜索过滤
+
+
+示例:
+
+curl -X GET \
+-d "name=Ada" \
+http://localhost:3000/api/ignores.json
+
await octokit.request('GET /api/ignores.json')
+
HTTP 请求
+GET api/ignores.json
+请求参数
+
+
+| 参数 |
+必选 |
+默认 |
+类型 |
+字段说明 |
+
+
+
+| name |
+否 |
+否 |
+ |
+string |
+
+
+返回字段说明
+
+
+| 参数 |
+类型 |
+字段说明 |
+
+
+
+| id |
+int |
+id |
+
+
+| name |
+string |
+gitignore名称 |
+
+
+
+
+返回的JSON示例:
+
+{
+ "ignores": [
+ {
+ "id": 1,
+ "name": "Ada"
+ }
+ ]
+}
+
+
+
+Users
获取当前登陆用户信息
+获取当前登陆用户信息
+
+
+示例:
+
+curl -X GET http://localhost:3000/api/users/me.json
+
await octokit.request('GET /api/users/me.json')
+
HTTP 请求
+GET api/users/me.json
+返回字段说明:
+
+
+| 参数 |
+类型 |
+字段说明 |
+
+
+
+| user_id |
+int |
+用户id |
+
+
+| username |
+string |
+用户名称 |
+
+
+| admin |
+boolean |
+是否为管理用户 |
+
+
+| login |
+string |
+登录名 |
+
+
+| image_url |
+string |
+用户头像 |
+
+
+
+
+返回的JSON示例:
+
+{
+ "username": "username",
+ "login": "login",
+ "user_id": 100000,
+ "image_url": "avatars/User/b",
+ "admin": false
+}
+
+
+待办事项-用户通知信息
+待办事项-用户通知信息
+
+
+示例:
+
+curl -X GET http://localhost:3000/api/users/yystopf/applied_messages.json
+
await octokit.request('GET /api/users/:login/applied_messages.json')
+
HTTP 请求
+GET /api/users/:login/applied_messages.json
+请求字段说明:
+
+
+| 参数 |
+类型 |
+字段说明 |
+
+
+
+| login |
+string |
+用户标识 |
+
+
+返回字段说明:
+
+
+| 参数 |
+类型 |
+字段说明 |
+
+
+
+| applied |
+object |
+通知主体 |
+
+
+| applied.id |
+int |
+通知主体的迁移id |
+
+
+| applied.status |
+string |
+通知主体的迁移状态,canceled:取消,common:正在迁移, accept:已接受,refuse:已拒绝 |
+
+
+| applied.time_ago |
+string |
+通知主体的迁移创建的时间 |
+
+
+| applied.project.id |
+int |
+通知主体的迁移项目的id |
+
+
+| applied.project.identifier |
+string |
+通知主体的迁移项目的标识 |
+
+
+| applied.project.name |
+string |
+通知主体的迁移项目的名称 |
+
+
+| applied.project.description |
+string |
+通知主体的迁移项目的描述 |
+
+
+| applied.project.is_public |
+bool |
+通知主体的迁移项目是否公开 |
+
+
+| applied.project.owner.id |
+bool |
+通知主体的迁移项目拥有者id |
+
+
+| applied.project.owner.type |
+string |
+通知主体的迁移项目拥有者类型 |
+
+
+| applied.project.owner.name |
+string |
+通知主体的迁移项目拥有者昵称 |
+
+
+| applied.project.owner.login |
+string |
+通知主体的迁移项目拥有者标识 |
+
+
+| applied.project.owner.image_url |
+string |
+通知主体的迁移项目拥有者头像 |
+
+
+| applied.user.id |
+int |
+通知主体的迁移创建者的id |
+
+
+| applied.user.type |
+string |
+通知主体的迁移创建者的类型 |
+
+
+| applied.user.name |
+string |
+通知主体的迁移创建者的名称 |
+
+
+| applied.user.login |
+string |
+通知主体的迁移创建者的标识 |
+
+
+| applied.user.image_url |
+string |
+通知主体的迁移创建者头像 |
+
+
+| applied.owner.id |
+int |
+通知主体的迁移接受者的id |
+
+
+| applied.owner.type |
+string |
+通知主体的迁移接受者的类型 |
+
+
+| applied.owner.name |
+string |
+通知主体的迁移接受者的名称 |
+
+
+| applied.owner.login |
+string |
+通知主体的迁移接受者的标识 |
+
+
+| applied.owner.image_url |
+string |
+通知主体的迁移接受者头像 |
+
+
+| applied_type |
+string |
+通知类型 |
+
+
+| name |
+string |
+通知内容 |
+
+
+| viewed |
+string |
+是否已读,waiting:未读,viewed:已读 |
+
+
+| status |
+string |
+通知状态, canceled:已取消,common: 正常,successed:成功,failure:失败 |
+
+
+| time_ago |
+string |
+通知时间 |
+
+
+
+
+返回的JSON示例:
+
+{
+ "total_count": 5,
+ "applied_messages": [
+ {
+ "applied": {
+ "project": {
+ "id": 86,
+ "identifier": "ceshi_repo1",
+ "name": "测试项目啊1",
+ "description": "二十多",
+ "is_public": true,
+ "owner": {
+ "id": 52,
+ "type": "Organization",
+ "name": "身份卡手动阀",
+ "login": "ceshi1",
+ "image_url": "images/avatars/Organization/52?t=1618805056"
+ }
+ },
+ "user": {
+ "id": 6,
+ "type": "User",
+ "name": "yystopf",
+ "login": "yystopf",
+ "image_url": "system/lets/letter_avatars/2/Y/241_125_89/120.png"
+ },
+ "owner": {
+ "id": 9,
+ "type": "Organization",
+ "name": "测试组织",
+ "login": "ceshi_org",
+ "image_url": "images/avatars/Organization/9?t=1612706073"
+ },
+ "id": 4,
+ "status": "common",
+ "created_at": "2021-04-26 09:54",
+ "time_ago": "35分钟前"
+ },
+ "applied_user": {
+ "id": 6,
+ "type": "User",
+ "name": "yystopf",
+ "login": "yystopf",
+ "image_url": "system/lets/letter_avatars/2/Y/241_125_89/120.png"
+ },
+ "applied_type": "AppliedTransferProject",
+ "name": "正在将【测试项目啊1】仓库转移给【测试组织】",
+ "viewed": "viewed",
+ "status": "common",
+ "created_at": "2021-04-26 09:54",
+ "time_ago": "35分钟前"
+ },
+ ...
+ ]
+}
+
待办事项-接受仓库
+待办事项-接受仓库
+
+
+示例:
+
+curl -X GET http://localhost:3000/api/users/yystopf/applied_transfer_projects.json
+
await octokit.request('GET /api/users/:login/applied_transfer_projects.json')
+
HTTP 请求
+GET /api/users/:login/applied_transfer_projects.json
+请求字段说明:
+
+
+| 参数 |
+类型 |
+字段说明 |
+
+
+
+| login |
+string |
+用户标识 |
+
+
+返回字段说明:
+
+
+| 参数 |
+类型 |
+字段说明 |
+
+
+
+| id |
+int |
+迁移id |
+
+
+| status |
+string |
+迁移状态,canceled:取消,common:正在迁移, accept:已接受,refuse:已拒绝 |
+
+
+| time_ago |
+string |
+迁移创建的时间 |
+
+
+| project.id |
+int |
+迁移项目的id |
+
+
+| project.identifier |
+string |
+迁移项目的标识 |
+
+
+| project.name |
+string |
+迁移项目的名称 |
+
+
+| project.description |
+string |
+迁移项目的描述 |
+
+
+| project.is_public |
+bool |
+迁移项目是否公开 |
+
+
+| project.owner.id |
+bool |
+迁移项目拥有者id |
+
+
+| project.owner.type |
+string |
+迁移项目拥有者类型 |
+
+
+| project.owner.name |
+string |
+迁移项目拥有者昵称 |
+
+
+| project.owner.login |
+string |
+迁移项目拥有者标识 |
+
+
+| project.owner.image_url |
+string |
+迁移项目拥有者头像 |
+
+
+| user.id |
+int |
+迁移创建者的id |
+
+
+| user.type |
+string |
+迁移创建者的类型 |
+
+
+| user.name |
+string |
+迁移创建者的名称 |
+
+
+| user.login |
+string |
+迁移创建者的标识 |
+
+
+| user.image_url |
+string |
+迁移创建者头像 |
+
+
+| owner.id |
+int |
+迁移接受者的id |
+
+
+| owner.type |
+string |
+迁移接受者的类型 |
+
+
+| owner.name |
+string |
+迁移接受者的名称 |
+
+
+| owner.login |
+string |
+迁移接受者的标识 |
+
+
+| owner.image_url |
+string |
+迁移接受者头像 |
+
+
+
+
+返回的JSON示例:
+
+{
+ "total_count": 4,
+ "applied_transfer_projects": [
+ {
+ "project": {
+ "id": 86,
+ "identifier": "ceshi_repo1",
+ "name": "测试项目啊1",
+ "description": "二十多",
+ "is_public": true,
+ "owner": {
+ "id": 52,
+ "type": "Organization",
+ "name": "身份卡手动阀",
+ "login": "ceshi1",
+ "image_url": "images/avatars/Organization/52?t=1618805056"
+ }
+ },
+ "user": {
+ "id": 6,
+ "type": "User",
+ "name": "yystopf",
+ "login": "yystopf",
+ "image_url": "system/lets/letter_avatars/2/Y/241_125_89/120.png"
+ },
+ "owner": {
+ "id": 52,
+ "type": "Organization",
+ "name": "身份卡手动阀",
+ "login": "ceshi1",
+ "image_url": "images/avatars/Organization/52?t=1618805056"
+ },
+ "id": 1,
+ "status": "canceled",
+ "created_at": "2021-04-25 18:06",
+ "time_ago": "16小时前"
+ },
+ ...
+ ]
+}
+
用户接受迁移
+用户接受迁移
+
+
+示例:
+
+curl -X POST http://localhost:3000/api/users/yystopf/applied_transfer_projects/2/accept.json
+
await octokit.request('GET /api/users/:login/applied_transfer_projects/:id/accept.json')
+
HTTP 请求
+GET /api/users/:login/applied_transfer_projects/:id/accept.json
+请求字段说明:
+
+
+| 参数 |
+类型 |
+字段说明 |
+
+
+
+| login |
+string |
+用户标识 |
+
+
+| id |
+int |
+迁移id |
+
+
+返回字段说明:
+
+
+| 参数 |
+类型 |
+字段说明 |
+
+
+
+| id |
+int |
+迁移id |
+
+
+| status |
+string |
+迁移状态,canceled:取消,common:正在迁移, accept:已接受,refuse:已拒绝 |
+
+
+| time_ago |
+string |
+迁移创建的时间 |
+
+
+| project.id |
+int |
+迁移项目的id |
+
+
+| project.identifier |
+string |
+迁移项目的标识 |
+
+
+| project.name |
+string |
+迁移项目的名称 |
+
+
+| project.description |
+string |
+迁移项目的描述 |
+
+
+| project.is_public |
+bool |
+迁移项目是否公开 |
+
+
+| project.owner.id |
+bool |
+迁移项目拥有者id |
+
+
+| project.owner.type |
+string |
+迁移项目拥有者类型 |
+
+
+| project.owner.name |
+string |
+迁移项目拥有者昵称 |
+
+
+| project.owner.login |
+string |
+迁移项目拥有者标识 |
+
+
+| project.owner.image_url |
+string |
+迁移项目拥有者头像 |
+
+
+| user.id |
+int |
+迁移创建者的id |
+
+
+| user.type |
+string |
+迁移创建者的类型 |
+
+
+| user.name |
+string |
+迁移创建者的名称 |
+
+
+| user.login |
+string |
+迁移创建者的标识 |
+
+
+| user.image_url |
+string |
+迁移创建者头像 |
+
+
+| owner.id |
+int |
+迁移接受者的id |
+
+
+| owner.type |
+string |
+迁移接受者的类型 |
+
+
+| owner.name |
+string |
+迁移接受者的名称 |
+
-| name |
-false |
+owner.login |
string |
-name of the license |
+迁移接受者的标识 |
+
+
+| owner.image_url |
+string |
+迁移接受者头像 |
-返回字段说明:
+返回的JSON示例:
{
- "licenses": [
- {
- "id": 57,
- "name": "AFL-1.2"
- },
- {
- "id": 76,
- "name": "AFL-3.0"
+ "project": {
+ "id": 86,
+ "identifier": "ceshi_repo1",
+ "name": "测试项目啊1",
+ "description": "二十多",
+ "is_public": true,
+ "owner": {
+ "id": 52,
+ "type": "Organization",
+ "name": "身份卡手动阀",
+ "login": "ceshi1",
+ "image_url": "images/avatars/Organization/52?t=1618805056"
+ }
},
- {
- "id": 214,
- "name": "AFL-1.1"
+ "user": {
+ "id": 6,
+ "type": "User",
+ "name": "yystopf",
+ "login": "yystopf",
+ "image_url": "system/lets/letter_avatars/2/Y/241_125_89/120.png"
},
- {
- "id": 326,
- "name": "AFL-2.1"
+ "owner": {
+ "id": 52,
+ "type": "Organization",
+ "name": "身份卡手动阀",
+ "login": "ceshi1",
+ "image_url": "images/avatars/Organization/52?t=1618805056"
},
- {
- "id": 350,
- "name": "AFL-2.0"
- }
- ]
+ "id": 1,
+ "status": "canceled",
+ "created_at": "2021-04-25 18:06",
+ "time_ago": "16小时前"
}
-
Gitignores
gitignore模板列表
-获取gitignore模板列表, 支持名称搜索过滤
+用户拒绝迁移
+用户拒绝迁移
示例:
-curl -X GET \
--d "name=Ada" \
-http://localhost:3000/api/ignores.json
-
await octokit.request('GET /api/ignores.json')
-
HTTP 请求
-GET api/ignores.json
-请求参数
+curl -X POST http://localhost:3000/api/users/yystopf/applied_transfer_projects/2/refuse.json
+
await octokit.request('GET /api/users/:login/applied_transfer_projects/:id/refuse.json')
+
HTTP 请求
+GET /api/users/:login/applied_transfer_projects/:id/refuse.json
+请求字段说明:
| 参数 |
-必选 |
-默认 |
类型 |
字段说明 |
-| name |
-否 |
-否 |
- |
+login |
string |
+用户标识 |
+
+
+| id |
+int |
+迁移id |
-返回字段说明
+返回字段说明:
| 参数 |
@@ -548,72 +1309,117 @@ http://localhost:3000/api/ignores.json
| id |
int |
-id |
+迁移id |
-| name |
+status |
string |
-gitignore名称 |
+迁移状态,canceled:取消,common:正在迁移, accept:已接受,refuse:已拒绝 |
-
-
-
-返回的JSON示例:
-
-{
- "ignores": [
- {
- "id": 1,
- "name": "Ada"
- }
- ]
-}
-
-
-Users
获取当前登陆用户信息
-获取当前登陆用户信息
-
-
-示例:
-
-curl -X GET http://localhost:3000/api/users/me.json
-
await octokit.request('GET /api/users/me.json')
-
HTTP 请求
-GET api/users/me.json
-返回字段说明:
-
-| 参数 |
-类型 |
-字段说明 |
+time_ago |
+string |
+迁移创建的时间 |
-
-| user_id |
+project.id |
int |
-用户id |
+迁移项目的id |
-| username |
+project.identifier |
string |
-用户名称 |
+迁移项目的标识 |
-| admin |
-boolean |
-是否为管理用户 |
+project.name |
+string |
+迁移项目的名称 |
-| login |
+project.description |
string |
-登录名 |
+迁移项目的描述 |
-| image_url |
+project.is_public |
+bool |
+迁移项目是否公开 |
+
+
+| project.owner.id |
+bool |
+迁移项目拥有者id |
+
+
+| project.owner.type |
string |
-用户头像 |
+迁移项目拥有者类型 |
+
+
+| project.owner.name |
+string |
+迁移项目拥有者昵称 |
+
+
+| project.owner.login |
+string |
+迁移项目拥有者标识 |
+
+
+| project.owner.image_url |
+string |
+迁移项目拥有者头像 |
+
+
+| user.id |
+int |
+迁移创建者的id |
+
+
+| user.type |
+string |
+迁移创建者的类型 |
+
+
+| user.name |
+string |
+迁移创建者的名称 |
+
+
+| user.login |
+string |
+迁移创建者的标识 |
+
+
+| user.image_url |
+string |
+迁移创建者头像 |
+
+
+| owner.id |
+int |
+迁移接受者的id |
+
+
+| owner.type |
+string |
+迁移接受者的类型 |
+
+
+| owner.name |
+string |
+迁移接受者的名称 |
+
+
+| owner.login |
+string |
+迁移接受者的标识 |
+
+
+| owner.image_url |
+string |
+迁移接受者头像 |
@@ -621,17 +1427,40 @@ Success — a happy kitten is an authenticated kitten!
返回的JSON示例:
{
- "username": "username",
- "login": "login",
- "user_id": 100000,
- "image_url": "avatars/User/b",
- "admin": false
+ "project": {
+ "id": 86,
+ "identifier": "ceshi_repo1",
+ "name": "测试项目啊1",
+ "description": "二十多",
+ "is_public": true,
+ "owner": {
+ "id": 52,
+ "type": "Organization",
+ "name": "身份卡手动阀",
+ "login": "ceshi1",
+ "image_url": "images/avatars/Organization/52?t=1618805056"
+ }
+ },
+ "user": {
+ "id": 6,
+ "type": "User",
+ "name": "yystopf",
+ "login": "yystopf",
+ "image_url": "system/lets/letter_avatars/2/Y/241_125_89/120.png"
+ },
+ "owner": {
+ "id": 52,
+ "type": "Organization",
+ "name": "身份卡手动阀",
+ "login": "ceshi1",
+ "image_url": "images/avatars/Organization/52?t=1618805056"
+ },
+ "id": 1,
+ "status": "canceled",
+ "created_at": "2021-04-25 18:06",
+ "time_ago": "16小时前"
}
-
-
-Projects
获取项目列表
+Projects
获取项目列表
获取项目列表,也可以更加相关条件过滤搜素
@@ -1653,11 +2482,18 @@ http://localhost:3000/api/ceshi1/ceshi_repo1/applied_transfer_projects/organizat
| string |
组织名称 |
+
+| description |
+string |
+组织描述 |
+
+
+| avatar_url |
+string|组织头像 |
+ |
+
-description|string|组织描述
-avatar_url|string|组织头像
-
返回的JSON示例:
@@ -1937,17 +2773,17 @@ avatar_url|string|组织头像
| id |
int |
-项目id |
+迁移id |
| status |
string |
-项目迁移状态,canceled:取消,common:正在迁移, accept:已接受,refuse:已拒绝 |
+迁移状态,canceled:取消,common:正在迁移, accept:已接受,refuse:已拒绝 |
| time_ago |
string |
-项目迁移创建的时间 |
+迁移创建的时间 |
| project.id |
From 96238c2e13e6932e188c6fa98622615de60558af Mon Sep 17 00:00:00 2001
From: "vilet.yy"
Date: Mon, 26 Apr 2021 11:04:10 +0800
Subject: [PATCH 04/12] fix
---
.../projects/applied_transfer_projects_controller.rb | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/controllers/projects/applied_transfer_projects_controller.rb b/app/controllers/projects/applied_transfer_projects_controller.rb
index ad6c9b19c..e62033f21 100644
--- a/app/controllers/projects/applied_transfer_projects_controller.rb
+++ b/app/controllers/projects/applied_transfer_projects_controller.rb
@@ -6,7 +6,7 @@ class Projects::AppliedTransferProjectsController < Projects::BaseController
end
def create
- @applied_transfer_project = Projects::ApplyTransferService.call(current_user, @project, params[:owner_name])
+ @applied_transfer_project = Projects::ApplyTransferService.call(current_user, @project, params)
rescue Exception => e
uid_logger_error(e.message)
tip_exception(e.message)
From 1d81548eb62284526cbf69bed632e53fa7ffb210 Mon Sep 17 00:00:00 2001
From: "vilet.yy"
Date: Mon, 26 Apr 2021 11:32:59 +0800
Subject: [PATCH 05/12] fix
---
app/models/project.rb | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/models/project.rb b/app/models/project.rb
index 0c30e13fa..170bae06a 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -112,7 +112,7 @@ class Project < ApplicationRecord
has_one :project_detail, dependent: :destroy
has_many :team_projects, dependent: :destroy
has_many :project_units, dependent: :destroy
- has_one :applied_transfer_project, dependent: :destroy
+ has_one :applied_transfer_project,-> { order created_at: :desc }, dependent: :destroy
after_save :check_project_members
scope :project_statics_select, -> {select(:id,:name, :is_public, :identifier, :status, :project_type, :user_id, :forked_count, :visits, :project_category_id, :project_language_id, :license_id, :ignore_id, :watchers_count, :created_on)}
From 28c8761f323a405fba82311e68789b8d45d4676d Mon Sep 17 00:00:00 2001
From: "vilet.yy"
Date: Mon, 26 Apr 2021 15:11:08 +0800
Subject: [PATCH 06/12] fix
---
app/controllers/users/applied_transfer_projects_controller.rb | 4 ++--
app/services/projects/accept_transfer_service.rb | 2 +-
app/services/projects/refuse_transfer_service.rb | 1 +
3 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/app/controllers/users/applied_transfer_projects_controller.rb b/app/controllers/users/applied_transfer_projects_controller.rb
index 74366bb55..3889f2eb6 100644
--- a/app/controllers/users/applied_transfer_projects_controller.rb
+++ b/app/controllers/users/applied_transfer_projects_controller.rb
@@ -4,10 +4,10 @@ class Users::AppliedTransferProjectsController < Users::BaseController
before_action :find_project, except: [:index]
def index
- user_collection_sql = AppliedTransferProject.where(owner_id: @_observed_user.id).to_sql
+ user_collection_sql = AppliedTransferProject.joins(project: [members: :roles]).where(members: {user_id: @_observed_user.id}, roles: {name: 'Manager'}).to_sql
org_collection_sql = AppliedTransferProject.where(owner_id: Organization.joins(team_users: :team).where(team_users: {user_id: @_observed_user.id}, teams: {authorize: %w(admin owner)} )).to_sql
@applied_transfer_projects = AppliedTransferProject.from("( #{ user_collection_sql } UNION #{ org_collection_sql } ) AS applied_transfer_projects")
- @applied_transfer_projects = paginate @applied_transfer_projects
+ @applied_transfer_projects = paginate @applied_transfer_projects.order("created_at desc")
end
# 接受迁移
diff --git a/app/services/projects/accept_transfer_service.rb b/app/services/projects/accept_transfer_service.rb
index 57cdfd54b..284499002 100644
--- a/app/services/projects/accept_transfer_service.rb
+++ b/app/services/projects/accept_transfer_service.rb
@@ -26,7 +26,7 @@ class Projects::AcceptTransferService < ApplicationService
private
def validate!
raise Error, '该仓库未在迁移' unless @applied_transfer_project.present? && @project.is_transfering
- raise Error, '未拥有接受转移权限' unless @user.admin? || @project.is_admin?(@user)
+ raise Error, '未拥有接受转移权限' unless @user.admin? || @project.manager?(@user)
end
def update_apply
diff --git a/app/services/projects/refuse_transfer_service.rb b/app/services/projects/refuse_transfer_service.rb
index 88d252465..b8199e65e 100644
--- a/app/services/projects/refuse_transfer_service.rb
+++ b/app/services/projects/refuse_transfer_service.rb
@@ -21,6 +21,7 @@ class Projects::RefuseTransferService < ApplicationService
private
def validate!
raise Error, '该仓库未在迁移' unless @applied_transfer_project.present? && @project.is_transfering
+ raise Error, '未拥有拒绝转移权限' unless @user.admin? || @project.manager?(@user)
end
def update_apply
From 220ca966696c50aada0dc986bd69ff5f580f7234 Mon Sep 17 00:00:00 2001
From: "vilet.yy"
Date: Mon, 26 Apr 2021 15:17:51 +0800
Subject: [PATCH 07/12] fix
---
app/controllers/users/applied_transfer_projects_controller.rb | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/app/controllers/users/applied_transfer_projects_controller.rb b/app/controllers/users/applied_transfer_projects_controller.rb
index 3889f2eb6..74366bb55 100644
--- a/app/controllers/users/applied_transfer_projects_controller.rb
+++ b/app/controllers/users/applied_transfer_projects_controller.rb
@@ -4,10 +4,10 @@ class Users::AppliedTransferProjectsController < Users::BaseController
before_action :find_project, except: [:index]
def index
- user_collection_sql = AppliedTransferProject.joins(project: [members: :roles]).where(members: {user_id: @_observed_user.id}, roles: {name: 'Manager'}).to_sql
+ user_collection_sql = AppliedTransferProject.where(owner_id: @_observed_user.id).to_sql
org_collection_sql = AppliedTransferProject.where(owner_id: Organization.joins(team_users: :team).where(team_users: {user_id: @_observed_user.id}, teams: {authorize: %w(admin owner)} )).to_sql
@applied_transfer_projects = AppliedTransferProject.from("( #{ user_collection_sql } UNION #{ org_collection_sql } ) AS applied_transfer_projects")
- @applied_transfer_projects = paginate @applied_transfer_projects.order("created_at desc")
+ @applied_transfer_projects = paginate @applied_transfer_projects
end
# 接受迁移
From 13768f97787236840b5cd81da3d14a678d1b2898 Mon Sep 17 00:00:00 2001
From: "vilet.yy"
Date: Mon, 26 Apr 2021 15:28:49 +0800
Subject: [PATCH 08/12] add: same repo condition
---
app/services/projects/apply_transfer_service.rb | 1 +
1 file changed, 1 insertion(+)
diff --git a/app/services/projects/apply_transfer_service.rb b/app/services/projects/apply_transfer_service.rb
index 7f33cc101..e8839167d 100644
--- a/app/services/projects/apply_transfer_service.rb
+++ b/app/services/projects/apply_transfer_service.rb
@@ -22,6 +22,7 @@ class Projects::ApplyTransferService < ApplicationService
private
def validate!
raise Error, '仓库标识不正确' if @project.identifier != params[:identifier]
+ raise Error, '新拥有者已经存在同名仓库!' if Project.where(user_id: @owner.id, identifier: params[:identifier]).present?
raise Error, '该仓库正在迁移' if @project.is_transfering
raise Error, '新拥有者不存在' unless @owner.present?
raise Error, '未拥有转移权限' unless is_permit_owner
From 0d828ead1f5e52915c64f330a7f733095bc0a15a Mon Sep 17 00:00:00 2001
From: "vilet.yy"
Date: Mon, 26 Apr 2021 16:50:50 +0800
Subject: [PATCH 09/12] fix:some bug
---
.../users/applied_transfer_projects_controller.rb | 2 +-
.../send_transfer_project_applied_message_job.rb | 13 +++++++++++--
app/services/projects/accept_transfer_service.rb | 12 +++++++++---
app/services/projects/refuse_transfer_service.rb | 10 ++++++++--
app/services/projects/transfer_service.rb | 1 +
5 files changed, 30 insertions(+), 8 deletions(-)
diff --git a/app/controllers/users/applied_transfer_projects_controller.rb b/app/controllers/users/applied_transfer_projects_controller.rb
index 74366bb55..b1777f526 100644
--- a/app/controllers/users/applied_transfer_projects_controller.rb
+++ b/app/controllers/users/applied_transfer_projects_controller.rb
@@ -7,7 +7,7 @@ class Users::AppliedTransferProjectsController < Users::BaseController
user_collection_sql = AppliedTransferProject.where(owner_id: @_observed_user.id).to_sql
org_collection_sql = AppliedTransferProject.where(owner_id: Organization.joins(team_users: :team).where(team_users: {user_id: @_observed_user.id}, teams: {authorize: %w(admin owner)} )).to_sql
@applied_transfer_projects = AppliedTransferProject.from("( #{ user_collection_sql } UNION #{ org_collection_sql } ) AS applied_transfer_projects")
- @applied_transfer_projects = paginate @applied_transfer_projects
+ @applied_transfer_projects = paginate @applied_transfer_projects.order("created_at desc")
end
# 接受迁移
diff --git a/app/jobs/send_transfer_project_applied_message_job.rb b/app/jobs/send_transfer_project_applied_message_job.rb
index ef05f266d..5f0c24c65 100644
--- a/app/jobs/send_transfer_project_applied_message_job.rb
+++ b/app/jobs/send_transfer_project_applied_message_job.rb
@@ -3,7 +3,7 @@ class SendTransferProjectAppliedMessageJob < ApplicationJob
def perform(applied_transfer_project, applied_user, message_status)
project = applied_transfer_project.project
- owner = applied_transfer_project.owner
+ owner = project.owner
return unless project.present?
return unless owner.present?
if owner.is_a?(Organization)
@@ -12,13 +12,22 @@ class SendTransferProjectAppliedMessageJob < ApplicationJob
receivers = project.managers
end
receivers.each do |rec|
+ next if applied_user.id == rec.user_id # 自己不要给自己发通知
AppliedMessage.create!(user_id: rec.user_id,
applied: applied_transfer_project,
status: message_status,
- name: build_name(project.name, owner.real_name, message_status),
+ name: build_name(project.name, applied_transfer_project&.owner&.real_name, message_status),
applied_user_id: applied_user.id,
project_id: project.id)
end
+ if message_status == 'successed' # 如果转移成功,给转移发起者发通知已转移成功
+ AppliedMessage.find_or_create_by!(user_id: applied_transfer_project.user_id,
+ applied: applied_transfer_project,
+ status: message_status,
+ name: build_name(project.name, applied_transfer_project&.owner&.real_name, message_status),
+ applied_user_id: applied_user.id,
+ project_id: project.id)
+ end
end
private
diff --git a/app/services/projects/accept_transfer_service.rb b/app/services/projects/accept_transfer_service.rb
index 284499002..c99885ca0 100644
--- a/app/services/projects/accept_transfer_service.rb
+++ b/app/services/projects/accept_transfer_service.rb
@@ -1,11 +1,12 @@
class Projects::AcceptTransferService < ApplicationService
- attr_accessor :applied_transfer_project
+ attr_accessor :applied_transfer_project, :owner
attr_reader :user, :project
def initialize(user, project)
@user = user
@project = project
@applied_transfer_project = project.applied_transfer_project
+ @owner = @applied_transfer_project.owner
end
def call
@@ -26,7 +27,12 @@ class Projects::AcceptTransferService < ApplicationService
private
def validate!
raise Error, '该仓库未在迁移' unless @applied_transfer_project.present? && @project.is_transfering
- raise Error, '未拥有接受转移权限' unless @user.admin? || @project.manager?(@user)
+ raise Error, '未拥有接受转移权限' unless is_permit_operator
+ end
+
+ def is_permit_operator
+ return true if @user == @owner
+ return @owner.is_a?(Organization) && @owner.is_admin?(@user)
end
def update_apply
@@ -34,7 +40,7 @@ class Projects::AcceptTransferService < ApplicationService
end
def operate_project
- @project = Projects::TransferService.call(@project, @applied_transfer_project.owner)
+ @project = Projects::TransferService.call(@project, @owner)
end
def send_apply_message
diff --git a/app/services/projects/refuse_transfer_service.rb b/app/services/projects/refuse_transfer_service.rb
index b8199e65e..1b81b5741 100644
--- a/app/services/projects/refuse_transfer_service.rb
+++ b/app/services/projects/refuse_transfer_service.rb
@@ -1,11 +1,12 @@
class Projects::RefuseTransferService < ApplicationService
- attr_accessor :applied_transfer_project
+ attr_accessor :applied_transfer_project, :owner
attr_reader :user, :project
def initialize(user, project)
@user = user
@project = project
@applied_transfer_project = project.applied_transfer_project
+ @owner = @applied_transfer_project.owner
end
def call
@@ -21,7 +22,12 @@ class Projects::RefuseTransferService < ApplicationService
private
def validate!
raise Error, '该仓库未在迁移' unless @applied_transfer_project.present? && @project.is_transfering
- raise Error, '未拥有拒绝转移权限' unless @user.admin? || @project.manager?(@user)
+ raise Error, '未拥有拒绝转移权限' unless is_permit_operator
+ end
+
+ def is_permit_operator
+ return true if @user == @owner
+ return @owner.is_a?(Organization) && @owner.is_admin?(@user)
end
def update_apply
diff --git a/app/services/projects/transfer_service.rb b/app/services/projects/transfer_service.rb
index b32b24817..4582a2103 100644
--- a/app/services/projects/transfer_service.rb
+++ b/app/services/projects/transfer_service.rb
@@ -23,6 +23,7 @@ class Projects::TransferService < ApplicationService
private
def update_owner
+ project.members.find_by(user_id: owner.id).destroy! if owner.is_a?(User)
project.update!(user_id: new_owner.id)
end
From 01360de423159d32f2c005feace855a30a771dbd Mon Sep 17 00:00:00 2001
From: "vilet.yy"
Date: Tue, 27 Apr 2021 13:56:12 +0800
Subject: [PATCH 10/12] fix: acceptor must exist
---
app/services/projects/apply_transfer_service.rb | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/services/projects/apply_transfer_service.rb b/app/services/projects/apply_transfer_service.rb
index e8839167d..28097bed5 100644
--- a/app/services/projects/apply_transfer_service.rb
+++ b/app/services/projects/apply_transfer_service.rb
@@ -22,9 +22,9 @@ class Projects::ApplyTransferService < ApplicationService
private
def validate!
raise Error, '仓库标识不正确' if @project.identifier != params[:identifier]
- raise Error, '新拥有者已经存在同名仓库!' if Project.where(user_id: @owner.id, identifier: params[:identifier]).present?
raise Error, '该仓库正在迁移' if @project.is_transfering
raise Error, '新拥有者不存在' unless @owner.present?
+ raise Error, '新拥有者已经存在同名仓库!' if Project.where(user_id: @owner.id, identifier: params[:identifier]).present?
raise Error, '未拥有转移权限' unless is_permit_owner
end
From b68c9945e54f34f3bcf45a474d2131555749a337 Mon Sep 17 00:00:00 2001
From: "vilet.yy"
Date: Tue, 27 Apr 2021 14:40:18 +0800
Subject: [PATCH 11/12] add: project edit transfer
---
app/views/repositories/edit.json.jbuilder | 5 ++++-
app/views/users/_user_simple.json.jbuilder | 14 +++++++++-----
2 files changed, 13 insertions(+), 6 deletions(-)
diff --git a/app/views/repositories/edit.json.jbuilder b/app/views/repositories/edit.json.jbuilder
index d268696cc..7a11411f4 100644
--- a/app/views/repositories/edit.json.jbuilder
+++ b/app/views/repositories/edit.json.jbuilder
@@ -9,4 +9,7 @@ json.website @project.website
json.project_units @project.project_units.pluck(:unit_type)
json.lesson_url @project.lesson_url
json.permission render_permission(current_user, @project)
-json.is_transfering @project.is_transfering
\ No newline at end of file
+json.is_transfering @project.is_transfering
+json.transfer do
+ json.partial! "/users/user_simple", locals: {user: @project&.applied_transfer_project&.owner}
+end
\ No newline at end of file
diff --git a/app/views/users/_user_simple.json.jbuilder b/app/views/users/_user_simple.json.jbuilder
index cfd06a405..5da161509 100644
--- a/app/views/users/_user_simple.json.jbuilder
+++ b/app/views/users/_user_simple.json.jbuilder
@@ -1,5 +1,9 @@
-json.id user.id
-json.type user.type
-json.name user.real_name
-json.login user.login
-json.image_url url_to_avatar(user)
\ No newline at end of file
+if user.present?
+ json.id user.id
+ json.type user.type
+ json.name user.real_name
+ json.login user.login
+ json.image_url url_to_avatar(user)
+else
+ json.nil!
+end
\ No newline at end of file
From 120a33bc8ab5ae09c79fb589c6eecb3a50269513 Mon Sep 17 00:00:00 2001
From: "vilet.yy"
Date: Tue, 27 Apr 2021 15:43:37 +0800
Subject: [PATCH 12/12] add: undo count
---
app/controllers/users_controller.rb | 2 ++
app/jobs/send_transfer_project_applied_message_job.rb | 6 +++---
app/views/users/show.json.jbuilder | 2 ++
3 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index c6ac626a3..395a5a6d9 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -32,6 +32,8 @@ class UsersController < ApplicationController
@common_applied_transfer_projects = AppliedTransferProject.where(owner_id: @user.id).common + AppliedTransferProject.where(owner_id: Organization.joins(team_users: :team).where(team_users: {user_id: @user.id}, teams: {authorize: %w(admin owner)} )).common
@undo_events = @waiting_applied_messages.size + @common_applied_transfer_projects.size
else
+ @waiting_applied_messages = AppliedMessage.none
+ @common_applied_transfer_projects = AppliedTransferProject.none
@undo_events = 0
end
#用户的组织数量
diff --git a/app/jobs/send_transfer_project_applied_message_job.rb b/app/jobs/send_transfer_project_applied_message_job.rb
index 5f0c24c65..92ea306d1 100644
--- a/app/jobs/send_transfer_project_applied_message_job.rb
+++ b/app/jobs/send_transfer_project_applied_message_job.rb
@@ -16,7 +16,7 @@ class SendTransferProjectAppliedMessageJob < ApplicationJob
AppliedMessage.create!(user_id: rec.user_id,
applied: applied_transfer_project,
status: message_status,
- name: build_name(project.name, applied_transfer_project&.owner&.real_name, message_status),
+ name: build_name(project.name, applied_transfer_project&.owner&.real_name, message_status, applied_user&.real_name),
applied_user_id: applied_user.id,
project_id: project.id)
end
@@ -31,7 +31,7 @@ class SendTransferProjectAppliedMessageJob < ApplicationJob
end
private
- def build_name(repo_name, owner_name, message_status)
+ def build_name(repo_name, owner_name, message_status, applied_name="")
case message_status
when 'canceled'
return "取消转移【#{repo_name}】仓库"
@@ -40,7 +40,7 @@ class SendTransferProjectAppliedMessageJob < ApplicationJob
when 'successed'
return "【#{repo_name}】仓库成功转移给【#{owner_name}】"
when 'failure'
- return "【#{repo_name}】仓库转移失败"
+ return "拒绝转移【#{repo_name}】仓库"
end
""
end
diff --git a/app/views/users/show.json.jbuilder b/app/views/users/show.json.jbuilder
index 54f85c5c2..e80ac7494 100644
--- a/app/views/users/show.json.jbuilder
+++ b/app/views/users/show.json.jbuilder
@@ -10,6 +10,8 @@ json.user_identity @user.identity
json.is_watch current_user&.watched?(@user)
json.watched_count @user.fan_count #粉丝
json.watching_count @user.follow_count #关注数
+json.undo_messages @waiting_applied_messages.size
+json.undo_transfer_projects @common_applied_transfer_projects.size
json.undo_events @undo_events
json.user_composes_count @user_composes_count
json.user_org_count @user_org_count