diff --git a/app/controllers/organizations/organizations_controller.rb b/app/controllers/organizations/organizations_controller.rb index 8346886e9..e03ddf121 100644 --- a/app/controllers/organizations/organizations_controller.rb +++ b/app/controllers/organizations/organizations_controller.rb @@ -18,6 +18,7 @@ class Organizations::OrganizationsController < Organizations::BaseController end def show + @can_create_project = @organization.can_create_project?(current_user.id) @is_admin = can_edit_org? @is_member = @organization.is_member?(current_user.id) end @@ -60,15 +61,15 @@ class Organizations::OrganizationsController < Organizations::BaseController private def convert_image! return unless params[:image].present? - max_size = EduSetting.get('upload_avatar_max_size').to_i || 2 * 1024 * 1024 # 2M + max_size = EduSetting.get('upload_avatar_max_size') || 2 * 1024 * 1024 # 2M if params[:image].class == ActionDispatch::Http::UploadedFile @image = params[:image] render_error('请上传文件') if @image.size.zero? - render_error('文件大小超过限制') if @image.size > max_size + render_error('文件大小超过限制') if @image.size > max_size.to_i else image = params[:image].to_s.strip return render_error('请上传正确的图片') if image.blank? - @image = Util.convert_base64_image(image, max_size: max_size) + @image = Util.convert_base64_image(image, max_size: max_size.to_i) end rescue Base64ImageConverter::Error => ex render_error(ex.message) diff --git a/app/controllers/organizations/teams_controller.rb b/app/controllers/organizations/teams_controller.rb index 577b3121a..47e95559f 100644 --- a/app/controllers/organizations/teams_controller.rb +++ b/app/controllers/organizations/teams_controller.rb @@ -15,6 +15,18 @@ class Organizations::TeamsController < Organizations::BaseController @teams = kaminari_paginate(@teams) end + def search + tip_exception("请输入搜索关键词") if params[:search].nil? + if @organization.is_owner?(current_user) || current_user.admin? + @teams = @organization.teams + else + @teams = @organization.teams.joins(:team_users).where(team_users: {user_id: current_user.id}) + end + @is_admin = can_edit_org? + @teams = @teams.ransack(name_cont: params[:search]).result if params[:search].present? + @teams = @teams.includes(:team_units, :team_users) + end + def show @is_admin = can_edit_org? @is_member = @team.is_member?(current_user.id) diff --git a/app/controllers/projects/teams_controller.rb b/app/controllers/projects/teams_controller.rb index d5b7ea1e8..b6ea32185 100644 --- a/app/controllers/projects/teams_controller.rb +++ b/app/controllers/projects/teams_controller.rb @@ -1,10 +1,47 @@ class Projects::TeamsController < Projects::BaseController + before_action :load_operate_team, only: [:create, :destroy] + before_action :load_team_project, only: :destroy + def index if @project.owner.is_a?(Organization) - @teams = @project.owner.teams + @teams = Team.joins(:team_projects).where(team_projects: {project_id: @project.id}) else @teams = Team.none end @teams = paginate(@teams) end + + def create + ActiveRecord::Base.transaction do + @team_project = TeamProject.build(@owner.id, @operate_team.id, @project.id) + Gitea::Organization::TeamProject::CreateService.call(@owner.gitea_token, @operate_team.gtid, @owner.login, @project.identifier) + render_ok + end + rescue Exception => e + uid_logger_error(e.message) + tip_exception(e.message) + end + + def destroy + ActiveRecord::Base.transaction do + @team_project.destroy! + Gitea::Organization::TeamProject::DeleteService.call(@owner.gitea_token, @operate_team.gtid, @owner.login, @project.identifier) + render_ok + end + rescue Exception => e + uid_logger_error(e.message) + tip_exception(e.message) + end + + private + def load_operate_team + @operate_team = Team.find_by(id: params[:team_id]) || Team.find_by(id: params[:id]) + tip_exception("项目不存在") if @operate_team.nil? + tip_exception("该组织团队拥有组织所有项目,无法进行操作") if @operate_team.includes_all_project + end + + def load_team_project + @team_project = TeamProject.find_by(organization_id: @owner.id, team_id: @operate_team.id, project_id: @project.id) + tip_exception("组织团队项目不存在") if @team_project.nil? + end end \ No newline at end of file diff --git a/app/models/concerns/project_operable.rb b/app/models/concerns/project_operable.rb index a45049882..5e8bf43d9 100644 --- a/app/models/concerns/project_operable.rb +++ b/app/models/concerns/project_operable.rb @@ -13,7 +13,7 @@ module ProjectOperable def add_member!(user_id, role_name='Developer') member = members.create!(user_id: user_id) - set_developer_role(member) + set_developer_role(member, role_name) end def remove_member!(user_id) @@ -84,8 +84,8 @@ module ProjectOperable end end - def set_developer_role(member) - role = Role.find_by_name 'Developer' + def set_developer_role(member, role_name) + role = Role.find_by(name: role_name) member.member_roles.create!(role: role) end diff --git a/app/models/organization.rb b/app/models/organization.rb index 06338bfd5..5c66c5ff4 100644 --- a/app/models/organization.rb +++ b/app/models/organization.rb @@ -78,6 +78,10 @@ class Organization < Owner self.create!(login: name, gitea_token: gitea_token) end + def can_create_project?(user_id) + team_users.joins(:team).where(user_id: user_id, teams: {can_create_org_project: true}).present? + end + def is_member?(user_id) organization_users.where(user_id: user_id).present? end diff --git a/app/models/project.rb b/app/models/project.rb index feb0d3067..f82674dbc 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -1,73 +1,73 @@ -# == Schema Information -# -# Table name: projects -# -# id :integer not null, primary key -# name :string(255) default(""), not null -# description :text(4294967295) -# homepage :string(255) default("") -# is_public :boolean default("1"), not null -# parent_id :integer -# created_on :datetime -# updated_on :datetime -# identifier :string(255) -# status :integer default("1"), not null -# lft :integer -# rgt :integer -# inherit_members :boolean default("0"), not null -# project_type :integer default("0") -# hidden_repo :boolean default("0"), not null -# attachmenttype :integer default("1") -# user_id :integer -# dts_test :integer default("0") -# enterprise_name :string(255) -# organization_id :integer -# project_new_type :integer -# gpid :integer -# forked_from_project_id :integer -# forked_count :integer default("0") -# publish_resource :integer default("0") -# visits :integer default("0") -# hot :integer default("0") -# invite_code :string(255) -# qrcode :string(255) -# qrcode_expiretime :integer default("0") -# script :text(65535) -# training_status :integer default("0") -# rep_identifier :string(255) -# project_category_id :integer -# project_language_id :integer -# license_id :integer -# ignore_id :integer -# praises_count :integer default("0") -# watchers_count :integer default("0") -# issues_count :integer default("0") -# pull_requests_count :integer default("0") -# language :string(255) -# versions_count :integer default("0") -# issue_tags_count :integer default("0") -# closed_issues_count :integer default("0") -# open_devops :boolean default("0") -# gitea_webhook_id :integer -# open_devops_count :integer default("0") -# recommend :boolean default("0") -# platform :integer default("0") -# -# Indexes -# -# index_projects_on_forked_from_project_id (forked_from_project_id) -# index_projects_on_identifier (identifier) -# index_projects_on_is_public (is_public) -# index_projects_on_lft (lft) -# index_projects_on_name (name) -# index_projects_on_platform (platform) -# index_projects_on_project_type (project_type) -# index_projects_on_recommend (recommend) -# index_projects_on_rgt (rgt) -# index_projects_on_status (status) -# index_projects_on_updated_on (updated_on) -# - +# == Schema Information +# +# Table name: projects +# +# id :integer not null, primary key +# name :string(255) default(""), not null +# description :text(4294967295) +# homepage :string(255) default("") +# is_public :boolean default("1"), not null +# parent_id :integer +# created_on :datetime +# updated_on :datetime +# identifier :string(255) +# status :integer default("1"), not null +# lft :integer +# rgt :integer +# inherit_members :boolean default("0"), not null +# project_type :integer default("0") +# hidden_repo :boolean default("0"), not null +# attachmenttype :integer default("1") +# user_id :integer +# dts_test :integer default("0") +# enterprise_name :string(255) +# organization_id :integer +# project_new_type :integer +# gpid :integer +# forked_from_project_id :integer +# forked_count :integer default("0") +# publish_resource :integer default("0") +# visits :integer default("0") +# hot :integer default("0") +# invite_code :string(255) +# qrcode :string(255) +# qrcode_expiretime :integer default("0") +# script :text(65535) +# training_status :integer default("0") +# rep_identifier :string(255) +# project_category_id :integer +# project_language_id :integer +# license_id :integer +# ignore_id :integer +# praises_count :integer default("0") +# watchers_count :integer default("0") +# issues_count :integer default("0") +# pull_requests_count :integer default("0") +# language :string(255) +# versions_count :integer default("0") +# issue_tags_count :integer default("0") +# closed_issues_count :integer default("0") +# open_devops :boolean default("0") +# gitea_webhook_id :integer +# open_devops_count :integer default("0") +# recommend :boolean default("0") +# platform :integer default("0") +# +# Indexes +# +# index_projects_on_forked_from_project_id (forked_from_project_id) +# index_projects_on_identifier (identifier) +# index_projects_on_is_public (is_public) +# index_projects_on_lft (lft) +# index_projects_on_name (name) +# index_projects_on_platform (platform) +# index_projects_on_project_type (project_type) +# index_projects_on_recommend (recommend) +# index_projects_on_rgt (rgt) +# index_projects_on_status (status) +# index_projects_on_updated_on (updated_on) +# + class Project < ApplicationRecord include Matchable @@ -108,6 +108,7 @@ class Project < ApplicationRecord has_many :praise_treads, as: :praise_tread_object, dependent: :destroy has_and_belongs_to_many :trackers, :order => "#{Tracker.table_name}.position" has_one :project_detail, dependent: :destroy + has_many :team_projects, 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)} diff --git a/app/models/user.rb b/app/models/user.rb index 250a9b8b2..1cb6670c6 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -135,8 +135,8 @@ class User < Owner has_many :attachments,foreign_key: :author_id, :dependent => :destroy # 关注 - has_many :be_watchers, foreign_key: :user_id, dependent: :destroy # 我的关注 - has_many :be_watcher_users, through: :be_watchers, dependent: :destroy # 我关注的用户 + # has_many :be_watchers, foreign_key: :user_id, dependent: :destroy # 我的关注 + # has_many :be_watcher_users, through: :be_watchers, dependent: :destroy # 我关注的用户 has_many :watchers, as: :watchable, dependent: :destroy has_one :ci_cloud_account, class_name: 'Ci::CloudAccount', dependent: :destroy diff --git a/app/services/repositories/create_service.rb b/app/services/repositories/create_service.rb index 9b89490fb..9da2fe94f 100644 --- a/app/services/repositories/create_service.rb +++ b/app/services/repositories/create_service.rb @@ -13,6 +13,7 @@ class Repositories::CreateService < ApplicationService ActiveRecord::Base.transaction do if repository.save! create_gitea_repository + create_manager_member sync_project sync_repository # if project.project_type == "common" @@ -51,6 +52,11 @@ class Repositories::CreateService < ApplicationService end end + def create_manager_member + return if project.owner.is_owner?(user.id) + project.add_member!(user.id, "Manager") + end + def sync_project if gitea_repository project.update_columns( diff --git a/app/views/organizations/organizations/show.json.jbuilder b/app/views/organizations/organizations/show.json.jbuilder index 2fd88b7b0..ab803751c 100644 --- a/app/views/organizations/organizations/show.json.jbuilder +++ b/app/views/organizations/organizations/show.json.jbuilder @@ -1,3 +1,4 @@ json.partial! "detail", organization: @organization +json.can_create_project @can_create_project json.is_admin @is_admin json.is_member @is_member \ No newline at end of file diff --git a/app/views/organizations/teams/search.json.jbuilder b/app/views/organizations/teams/search.json.jbuilder new file mode 100644 index 000000000..c07b8b870 --- /dev/null +++ b/app/views/organizations/teams/search.json.jbuilder @@ -0,0 +1,4 @@ +json.total_count @teams.size +json.teams @teams do |team| + json.partial! "detail", team: team, organization: @organization +end diff --git a/app/views/projects/teams/index.json.jbuilder b/app/views/projects/teams/index.json.jbuilder index f6f7572b8..0a48e884d 100644 --- a/app/views/projects/teams/index.json.jbuilder +++ b/app/views/projects/teams/index.json.jbuilder @@ -1,4 +1,5 @@ json.total_count @teams.total_count json.teams @teams.each do |team| json.(team, :id, :name, :authorize) + json.can_remove !team.includes_all_project && team&.organization&.repo_admin_change_team_access end \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 1a1fffd22..2d8861416 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -113,6 +113,9 @@ Rails.application.routes.draw do end end resources :teams, except: [:edit, :new] do + collection do + get :search + end resources :team_users, only: [:index, :create, :destroy] do collection do delete :quit @@ -519,7 +522,7 @@ Rails.application.routes.draw do end scope module: :projects do - resources :teams, only: [:index] + resources :teams, only: [:index, :create, :destroy] scope do get( '/blob/*id/diff',