diff --git a/app/assets/javascripts/admins/organizations.js b/app/assets/javascripts/admins/organizations.js new file mode 100644 index 000000000..dee720fac --- /dev/null +++ b/app/assets/javascripts/admins/organizations.js @@ -0,0 +1,2 @@ +// Place all the behaviors and hooks related to the matching controller here. +// All this logic will automatically be available in application.js. diff --git a/app/assets/stylesheets/admins/organizations.scss b/app/assets/stylesheets/admins/organizations.scss new file mode 100644 index 000000000..a3cf9ca1f --- /dev/null +++ b/app/assets/stylesheets/admins/organizations.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the admins/organizations controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/controllers/admins/organizations_controller.rb b/app/controllers/admins/organizations_controller.rb new file mode 100644 index 000000000..35fb4dee8 --- /dev/null +++ b/app/controllers/admins/organizations_controller.rb @@ -0,0 +1,27 @@ +class Admins::OrganizationsController < Admins::BaseController + before_action :finder_org, except: [:index] + + def index + params[:sort_by] = params[:sort_by].presence || 'created_on' + params[:sort_direction] = params[:sort_direction].presence || 'desc' + + orgs = Admins::OrganizationQuery.call(params) + @orgs = paginate orgs + end + + def show + end + + def destroy + @org.destroy! + Admins::DeleteOrganizationService.call(@org.login) + render_delete_success + end + + private + + def finder_org + @org = Organization.find(params[:id]) + end + +end diff --git a/app/helpers/admins/organizations_helper.rb b/app/helpers/admins/organizations_helper.rb new file mode 100644 index 000000000..0265ab1e4 --- /dev/null +++ b/app/helpers/admins/organizations_helper.rb @@ -0,0 +1,2 @@ +module Admins::OrganizationsHelper +end diff --git a/app/models/organization.rb b/app/models/organization.rb index adf43a2cd..d61dda567 100644 --- a/app/models/organization.rb +++ b/app/models/organization.rb @@ -144,6 +144,18 @@ class Organization < Owner end end + def projects_count + Project.where( user_id: self.id).count + end + + def teams_count + teams.count + end + + def organization_users_count + organization_users.count + end + def real_name name = lastname + firstname name = name.blank? ? (nickname.blank? ? login : nickname) : name diff --git a/app/queries/admins/organization_query.rb b/app/queries/admins/organization_query.rb new file mode 100644 index 000000000..09dbab9e3 --- /dev/null +++ b/app/queries/admins/organization_query.rb @@ -0,0 +1,21 @@ +class Admins::OrganizationQuery < ApplicationQuery + include CustomSortable + attr_reader :params + sort_columns :created_on, :last_login_on, :experience, :grade, default_by: :created_on, default_direction: :desc + + def initialize(params) + @params = params + end + + def call + orgs = Organization.all + # 关键字检索 + keyword = params[:keyword].to_s.strip.presence + if keyword + sql = 'nickname LIKE :keyword OR login LIKE :keyword' + orgs = orgs.where(sql, keyword: "%#{keyword}%") + end + + custom_sort(orgs, params[:sort_by], params[:sort_direction]) + end +end \ No newline at end of file diff --git a/app/services/admins/delete_organization_service.rb b/app/services/admins/delete_organization_service.rb new file mode 100644 index 000000000..f5760b364 --- /dev/null +++ b/app/services/admins/delete_organization_service.rb @@ -0,0 +1,19 @@ +class Admins::DeleteOrganizationService < Gitea::ClientService + attr_reader :token, :name + + def initialize(name) + @name = name + end + + def call + Gitea::Organization::DeleteService.call(token,name) + end + + private + def token + { + username: GiteaService.gitea_config[:access_key_id], + password: GiteaService.gitea_config[:access_key_secret] + } + end +end diff --git a/app/views/admins/organizations/edit.html.erb b/app/views/admins/organizations/edit.html.erb new file mode 100644 index 000000000..0cc9909f0 --- /dev/null +++ b/app/views/admins/organizations/edit.html.erb @@ -0,0 +1,41 @@ +<% + define_admin_breadcrumbs do + add_admin_breadcrumb('组织管理', admins_organizations_path) + add_admin_breadcrumb('组织详情') + end +%> + +
+
+ <%= link_to "/#{@org.login}", class: 'user-info-avatar col-md-1', target: '_blank', data: { toggle: 'tooltip', title: '个人中心' } do %> + + <% end %> + +
+ + <%= simple_form_for(@org, url: admins_organization_path(@org)) do |f| %> + +
基本信息
+
+
+ <%= f.input :login, label: '登录名', wrapper_html: { class: 'col-md-3' }, input_html: { readonly: true, class: 'col-md-11', value: @org.login } %> +
+ +
+ <%= f.input :lastname, label: '姓名', wrapper_html: { class: 'col-md-3' }, input_html: { class: 'col-md-11', value: @org.real_name } %> +
+ + +
+ +
+ <%= f.button :submit, value: '保存', class: 'btn-primary mr-3 px-4' %> + <%= link_to '取消', admins_organizations_path, class: 'btn btn-secondary px-4' %> +
+ <% end %> +
diff --git a/app/views/admins/organizations/index.html.erb b/app/views/admins/organizations/index.html.erb new file mode 100644 index 000000000..7cd2ba8fa --- /dev/null +++ b/app/views/admins/organizations/index.html.erb @@ -0,0 +1,17 @@ +<% define_admin_breadcrumbs do %> + <% add_admin_breadcrumb('组织管理', admins_organizations_path) %> +<% end %> +
+ <%= form_tag(admins_organizations_path, method: :get, class: 'form-inline search-form flex-1', remote: true) do %> + + <%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-sm-2 ml-3', placeholder: 'login/昵称') %> + + <%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %> + <% end %> + +
+ +
+ <%= render partial: 'admins/organizations/shared/org_list', locals: { organizations: @orgs } %> +
+ diff --git a/app/views/admins/organizations/index.js.erb b/app/views/admins/organizations/index.js.erb new file mode 100644 index 000000000..5cf62a739 --- /dev/null +++ b/app/views/admins/organizations/index.js.erb @@ -0,0 +1 @@ +$('.organizations-list-container').html("<%= j( render partial: 'admins/organizations/shared/org_list', locals: { organizations: @orgs } ) %>"); \ No newline at end of file diff --git a/app/views/admins/organizations/index.json.jbuilder b/app/views/admins/organizations/index.json.jbuilder new file mode 100644 index 000000000..1278c3c13 --- /dev/null +++ b/app/views/admins/organizations/index.json.jbuilder @@ -0,0 +1,6 @@ +json.count @orgs.total_count +json.orgs do + json.array! @orgs.each do |org| + json.extract! org, :id, :login, :nickname + end +end \ No newline at end of file diff --git a/app/views/admins/organizations/shared/_org_list.html.erb b/app/views/admins/organizations/shared/_org_list.html.erb new file mode 100644 index 000000000..25878b296 --- /dev/null +++ b/app/views/admins/organizations/shared/_org_list.html.erb @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + <% if organizations.present? %> + <% organizations.each_with_index do |org, index| %> + + + + + + + + + + + <% end %> + <% else %> + <%= render 'admins/shared/no_data_for_table' %> + <% end %> + +
序号login昵称<%= sort_tag('创建于', name: 'created_on', path: admins_organizations_path) %>团队成员项目数操作
<%= list_index_no((params[:page] || 1).to_i, index) %> + <%= link_to "/#{org.login}", target: '_blank' do %> + <%= overflow_hidden_span org.login, width: 100 %> + <% end %> + <%= org.nickname %> <%= display_text(org.created_on&.strftime('%Y-%m-%d %H:%M')) %><%= link_to org.teams_count, "/#{org.login}", target: "_blank" %><%= link_to org.organization_users_count, "/#{org.login}", target: "_blank" %><%= link_to org.projects_count, "/#{org.login}", target: "_blank" %> + <%= link_to '查看', admins_organization_path(org), class: 'action' %> +
+ <%= javascript_void_link('更多', class: 'action dropdown-toggle', 'data-toggle': 'dropdown', 'aria-haspopup': true, 'aria-expanded': false) %> + +
+
+ +<%= render partial: 'admins/shared/paginate', locals: { objects: organizations } %> diff --git a/app/views/admins/organizations/shared/_project_list.html.erb b/app/views/admins/organizations/shared/_project_list.html.erb new file mode 100644 index 000000000..e828938ff --- /dev/null +++ b/app/views/admins/organizations/shared/_project_list.html.erb @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + <% if projects.present? %> + <% projects.each_with_index do |project, index| %> + + + + + + + + + + + + + + + + <% end %> + <% else %> + <%= render 'admins/shared/no_data_for_table' %> + <% end %> + +
序号ID项目名称公开推荐Issues资源Pulls里程碑成员管理员<%= sort_tag('创建时间', name: 'created_on', path: admins_projects_path) %>操作
<%= list_index_no((params[:page] || 1).to_i, index) %><%= project.id %> + <%= link_to(project.name, "/#{project&.owner&.login}/#{project.identifier}", target: '_blank') %> + <%= project.is_public ? '√' : '' %><%= project.recommend ? '√' : '' %><%= project.issues.size %><%= project.attachments.size %><%= project&.pull_requests_count %><%= project.versions.size %><%= project.members.size %> + <%= link_to_project(project) %> + <%= project.created_on&.strftime('%Y-%m-%d %H:%M') %> + <% if project.is_public %> + <%= javascript_void_link '推荐', class: 'action recommend-action', data: { id: project.id }, style: project.recommend ? 'display: none;' : '' %> + <%= javascript_void_link '取消推荐', class: 'action unrecommend-action', data: { id: project.id }, style: project.recommend ? '' : 'display: none;' %> + <%= link_to "设置推荐等级", edit_admins_project_path(project.id), remote: true, class: "action edit-recommend-action", style: project.recommend ? '' : 'display: none;' %> + <% end %> + <%= link_to "删除", admins_project_path(project.id), method: :delete, data:{confirm: "确认删除的吗?"}, class: "delete-project-action" %> +
\ No newline at end of file diff --git a/app/views/admins/organizations/show.html.erb b/app/views/admins/organizations/show.html.erb new file mode 100644 index 000000000..b40f1c258 --- /dev/null +++ b/app/views/admins/organizations/show.html.erb @@ -0,0 +1,38 @@ +<% + define_admin_breadcrumbs do + add_admin_breadcrumb('组织管理', admins_organizations_path) + add_admin_breadcrumb('组织详情') + end +%> + +
+
+ <%= link_to "/#{@org.login}", class: 'user-info-avatar col-md-1', target: '_blank', data: { toggle: 'tooltip', title: '个人中心' } do %> + + <% end %> + +
+ + <%= simple_form_for(@org, url: admins_organization_path(@org)) do |f| %> + +
基本信息
+
+
+ <%= f.input :login, label: '登录名', wrapper_html: { class: 'col-md-3' }, input_html: { readonly: true, class: 'col-md-11', value: @org.login } %> +
+ +
+ <%= f.input :lastname, label: '姓名', wrapper_html: { class: 'col-md-3' }, input_html: { readonly: true, class: 'col-md-11', value: @org.real_name } %> +
+ + +
+ <% end %> +

组织项目

+ <%= render partial: 'admins/organizations/shared/project_list', locals: { projects: @org.projects } %> + +
diff --git a/app/views/admins/shared/_sidebar.html.erb b/app/views/admins/shared/_sidebar.html.erb index dc2d2944e..37f819bde 100644 --- a/app/views/admins/shared/_sidebar.html.erb +++ b/app/views/admins/shared/_sidebar.html.erb @@ -23,6 +23,7 @@
  • <%= sidebar_item_group('#user-submenu', '用户', icon: 'user') do %>
  • <%= sidebar_item(admins_users_path, '用户列表', icon: 'user', controller: 'admins-users') %>
  • +
  • <%= sidebar_item(admins_organizations_path, '组织列表', icon: 'user', controller: 'admins-organization') %>
  • <% end %>
  • diff --git a/config/routes.rb b/config/routes.rb index 3d6cc8f55..3488bacb4 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -816,7 +816,7 @@ Rails.application.routes.draw do resources :school_statistics, only: [:index] do get :contrast, on: :collection end - + resources :organizations, only: [:index, :edit, :show, :destroy] resources :users, only: [:index, :edit, :update, :destroy] do member do post :reward_grade diff --git a/spec/controllers/admins/organizations_controller_spec.rb b/spec/controllers/admins/organizations_controller_spec.rb new file mode 100644 index 000000000..a0df61f17 --- /dev/null +++ b/spec/controllers/admins/organizations_controller_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe Admins::OrganizationsController, type: :controller do + +end diff --git a/spec/helpers/admins/organizations_helper_spec.rb b/spec/helpers/admins/organizations_helper_spec.rb new file mode 100644 index 000000000..2f0a719a0 --- /dev/null +++ b/spec/helpers/admins/organizations_helper_spec.rb @@ -0,0 +1,15 @@ +require 'rails_helper' + +# Specs in this file have access to a helper object that includes +# the Admins::OrganizationsHelper. For example: +# +# describe Admins::OrganizationsHelper do +# describe "string concat" do +# it "concats two strings with spaces" do +# expect(helper.concat_strings("this","that")).to eq("this that") +# end +# end +# end +RSpec.describe Admins::OrganizationsHelper, type: :helper do + pending "add some examples to (or delete) #{__FILE__}" +end