forked from Gitlink/forgeplus
后台组织管理
This commit is contained in:
parent
a35e24468c
commit
8e547c178a
|
@ -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.
|
|
@ -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/
|
|
@ -0,0 +1,23 @@
|
|||
class Admins::OrganizationsController < Admins::BaseController
|
||||
before_action :finder_org, except: [:index]
|
||||
|
||||
def index
|
||||
@orgs = paginate Organization.all
|
||||
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
|
|
@ -0,0 +1,2 @@
|
|||
module Admins::OrganizationsHelper
|
||||
end
|
|
@ -144,6 +144,57 @@ class Organization < Owner
|
|||
end
|
||||
end
|
||||
|
||||
def projects_count
|
||||
Project.where( user_id: self.id).count
|
||||
end
|
||||
|
||||
# 用户账号状态
|
||||
def active?
|
||||
status == User::STATUS_ACTIVE
|
||||
end
|
||||
|
||||
def registered?
|
||||
status == User::STATUS_REGISTERED
|
||||
end
|
||||
|
||||
def locked?
|
||||
status == User::STATUS_LOCKED
|
||||
end
|
||||
|
||||
def need_edit_info?
|
||||
status == User::STATUS_EDIT_INFO
|
||||
end
|
||||
|
||||
def activate
|
||||
self.status = User::STATUS_ACTIVE
|
||||
end
|
||||
|
||||
def register
|
||||
self.status = User::STATUS_REGISTERED
|
||||
end
|
||||
|
||||
def lock
|
||||
self.status = User::STATUS_LOCKED
|
||||
end
|
||||
|
||||
def need_edit_info
|
||||
self.status = User::STATUS_EDIT_INFO
|
||||
end
|
||||
|
||||
def activate!
|
||||
update_attribute(:status, STATUS_ACTIVE)
|
||||
prohibit_gitea_user_login!(false)
|
||||
end
|
||||
|
||||
def register!
|
||||
update_attribute(:status, STATUS_REGISTERED)
|
||||
end
|
||||
|
||||
def lock!
|
||||
update_attribute(:status, STATUS_LOCKED)
|
||||
prohibit_gitea_user_login!
|
||||
end
|
||||
|
||||
def real_name
|
||||
name = lastname + firstname
|
||||
name = name.blank? ? (nickname.blank? ? login : nickname) : name
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
class Admins::DeleteOrganizationService < Gitea::ClientService
|
||||
attr_reader :token, :name
|
||||
|
||||
def initialize(name)
|
||||
@name = name
|
||||
end
|
||||
|
||||
def call
|
||||
response = delete(url, params)
|
||||
render_status(response)
|
||||
end
|
||||
|
||||
private
|
||||
def params
|
||||
Hash.new.merge(token: token)
|
||||
end
|
||||
|
||||
def url
|
||||
"/orgs/#{name}".freeze
|
||||
end
|
||||
|
||||
def token
|
||||
{
|
||||
username: GiteaService.gitea_config[:access_key_id],
|
||||
password: GiteaService.gitea_config[:access_key_secret]
|
||||
}
|
||||
end
|
||||
end
|
|
@ -0,0 +1,41 @@
|
|||
<%
|
||||
define_admin_breadcrumbs do
|
||||
add_admin_breadcrumb('组织管理', admins_organizations_path)
|
||||
add_admin_breadcrumb('组织详情')
|
||||
end
|
||||
%>
|
||||
|
||||
<div class="box user-edit-container">
|
||||
<div class="user-info mb-4 row">
|
||||
<%= link_to "/#{@org.login}", class: 'user-info-avatar col-md-1', target: '_blank', data: { toggle: 'tooltip', title: '个人中心' } do %>
|
||||
<img src="/<%= url_to_avatar(@org) %>" class="rounded-circle" width="80" height="80" />
|
||||
<% end %>
|
||||
<div class="d-flex flex-column justify-content-between col-md-3 user-info-content">
|
||||
<div class="user-info-name flex"><%= @org.nickname %> | <%= @org.id %> | <%= @org.login %></div>
|
||||
|
||||
|
||||
<div class="user-info-last-login">最近登录:<%= @org.last_login_on&.strftime('%Y-%m-%d %H:%M') %></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%= simple_form_for(@org, url: admins_organization_path(@org)) do |f| %>
|
||||
|
||||
<div><h6>基本信息</h6></div>
|
||||
<div class="form-group px-2">
|
||||
<div class="form-row">
|
||||
<%= f.input :login, label: '登录名', wrapper_html: { class: 'col-md-3' }, input_html: { readonly: true, class: 'col-md-11', value: @org.login } %>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<%= f.input :lastname, label: '姓名', wrapper_html: { class: 'col-md-3' }, input_html: { class: 'col-md-11', value: @org.real_name } %>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="form-row mt-4">
|
||||
<%= f.button :submit, value: '保存', class: 'btn-primary mr-3 px-4' %>
|
||||
<%= link_to '取消', admins_organizations_path, class: 'btn btn-secondary px-4' %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
|
@ -0,0 +1,8 @@
|
|||
<% define_admin_breadcrumbs do %>
|
||||
<% add_admin_breadcrumb('组织管理', admins_organizations_path) %>
|
||||
<% end %>
|
||||
|
||||
<div class="box admin-list-container organizations-list-container">
|
||||
<%= render partial: 'admins/organizations/shared/org_list', locals: { organizations: @orgs } %>
|
||||
</div>
|
||||
|
|
@ -0,0 +1 @@
|
|||
$('.users-list-container').html("<%= j( render partial: 'admins/organizations/shared/org_list', locals: { organizations: @orgs } ) %>");
|
|
@ -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
|
|
@ -0,0 +1,45 @@
|
|||
<table class="table table-hover users-list-table">
|
||||
<thead class="thead-light">
|
||||
<tr>
|
||||
<th width="4%">序号</th>
|
||||
<th width="8%" class="text-left">login</th>
|
||||
<th width="8%" class="text-left">昵称</th>
|
||||
<th width="10%"><%= sort_tag('创建于', name: 'created_on', path: admins_organizations_path) %></th>
|
||||
<th width="10%"><%= sort_tag('最后登录', name: 'last_login_on', path: admins_organizations_path) %></th>
|
||||
<th width="12%">项目数</th>
|
||||
<th width="14%">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% if organizations.present? %>
|
||||
<% organizations.each_with_index do |org, index| %>
|
||||
<tr class="org-item-<%= org.id %>">
|
||||
<td><%= list_index_no((params[:page] || 1).to_i, index) %></td>
|
||||
<td class="text-left">
|
||||
<%= link_to "/#{org.login}", target: '_blank' do %>
|
||||
<%= overflow_hidden_span org.login, width: 100 %>
|
||||
<% end %>
|
||||
</td>
|
||||
<td><%= org.nickname %> </td>
|
||||
<td><%= display_text(org.created_on&.strftime('%Y-%m-%d %H:%M')) %></td>
|
||||
<td><%= display_text(org.last_login_on&.strftime('%Y-%m-%d %H:%M')) %></td>
|
||||
<td><%= link_to org.projects_count, "/#{org.login}", target: "_blank" %></td>
|
||||
<td class="action-container">
|
||||
<%= link_to '查看', admins_organization_path(org), class: 'action' %>
|
||||
<div class="d-inline">
|
||||
<%= javascript_void_link('更多', class: 'action dropdown-toggle', 'data-toggle': 'dropdown', 'aria-haspopup': true, 'aria-expanded': false) %>
|
||||
<div class="dropdown-menu more-action-dropdown">
|
||||
|
||||
<%= delete_link '删除', admins_organization_path(org, element: ".user-item-#{org.id}"), class: 'dropdown-item delete-user-action' %>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<%= render 'admins/shared/no_data_for_table' %>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<%= render partial: 'admins/shared/paginate', locals: { objects: organizations } %>
|
|
@ -0,0 +1,53 @@
|
|||
<table class="table table-hover text-center subject-list-table">
|
||||
<thead class="thead-light">
|
||||
<tr>
|
||||
<th width="5%">序号</th>
|
||||
<th width="6%">ID</th>
|
||||
<th width="20%" class="text-left">项目名称</th>
|
||||
<th width="5%">公开</th>
|
||||
<th width="5%">推荐</th>
|
||||
<th width="5%">Issues</th>
|
||||
<th width="5%">资源</th>
|
||||
<th width="5%">Pulls</th>
|
||||
<th width="6%">里程碑</th>
|
||||
<th width="5%">成员</th>
|
||||
<th width="12%">管理员</th>
|
||||
<th width="15%"><%= sort_tag('创建时间', name: 'created_on', path: admins_projects_path) %></th>
|
||||
<th width="15%">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% if projects.present? %>
|
||||
<% projects.each_with_index do |project, index| %>
|
||||
<tr class="project-item-<%= project.id %>">
|
||||
<td><%= list_index_no((params[:page] || 1).to_i, index) %></td>
|
||||
<td><%= project.id %></td>
|
||||
<td class="text-left">
|
||||
<%= link_to(project.name, "/#{project&.owner&.login}/#{project.identifier}", target: '_blank') %>
|
||||
</td>
|
||||
<td><%= project.is_public ? '√' : '' %></td>
|
||||
<td><%= project.recommend ? '√' : '' %></td>
|
||||
<td><%= project.issues.size %></td>
|
||||
<td><%= project.attachments.size %></td>
|
||||
<td><%= project&.pull_requests_count %></td>
|
||||
<td><%= project.versions.size %></td>
|
||||
<td><%= project.members.size %></td>
|
||||
<td>
|
||||
<%= link_to_project(project) %>
|
||||
</td>
|
||||
<td><%= project.created_on&.strftime('%Y-%m-%d %H:%M') %></td>
|
||||
<td class="action-container">
|
||||
<% 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" %>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<%= render 'admins/shared/no_data_for_table' %>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
|
@ -0,0 +1,38 @@
|
|||
<%
|
||||
define_admin_breadcrumbs do
|
||||
add_admin_breadcrumb('组织管理', admins_organizations_path)
|
||||
add_admin_breadcrumb('组织详情')
|
||||
end
|
||||
%>
|
||||
|
||||
<div class="box user-edit-container">
|
||||
<div class="user-info mb-4 row">
|
||||
<%= link_to "/#{@org.login}", class: 'user-info-avatar col-md-1', target: '_blank', data: { toggle: 'tooltip', title: '个人中心' } do %>
|
||||
<img src="/<%= url_to_avatar(@org) %>" class="rounded-circle" width="80" height="80" />
|
||||
<% end %>
|
||||
<div class="d-flex flex-column justify-content-between col-md-3 user-info-content">
|
||||
<div class="user-info-name flex"><%= @org.nickname %> | <%= @org.id %> | <%= @org.login %></div>
|
||||
|
||||
<div class="user-info-last-login">最近登录:<%= @org.last_login_on&.strftime('%Y-%m-%d %H:%M') %></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%= simple_form_for(@org, url: admins_organization_path(@org)) do |f| %>
|
||||
|
||||
<div><h6>基本信息</h6></div>
|
||||
<div class="form-group px-2">
|
||||
<div class="form-row">
|
||||
<%= f.input :login, label: '登录名', wrapper_html: { class: 'col-md-3' }, input_html: { readonly: true, class: 'col-md-11', value: @org.login } %>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<%= f.input :lastname, label: '姓名', wrapper_html: { class: 'col-md-3' }, input_html: { readonly: true, class: 'col-md-11', value: @org.real_name } %>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
<% end %>
|
||||
<h3> 组织项目 </h3>
|
||||
<%= render partial: 'admins/organizations/shared/project_list', locals: { projects: @org.projects } %>
|
||||
|
||||
</div>
|
|
@ -15,14 +15,15 @@
|
|||
<ul class="list-unstyled components">
|
||||
<li><%= sidebar_item(admins_path, '概览', icon: 'dashboard', controller: 'admins-dashboards') %></li>
|
||||
<li>
|
||||
<%= sidebar_item_group('#user-submenu', '排行榜', icon: 'user') do %>
|
||||
<%= sidebar_item_group('#rank-submenu', '排行榜', icon: 'calendar') do %>
|
||||
<li><%= sidebar_item(admins_users_rank_index_path, '用户排行榜', icon: 'user', controller: 'admins-users_rank') %></li>
|
||||
<li><%= sidebar_item(admins_projects_rank_index_path, '项目排行榜', icon: 'user', controller: 'admins-projects_rank') %></li>
|
||||
<li><%= sidebar_item(admins_projects_rank_index_path, '项目排行榜', icon: 'database', controller: 'admins-projects_rank') %></li>
|
||||
<% end %>
|
||||
</li>
|
||||
<li>
|
||||
<%= sidebar_item_group('#user-submenu', '用户', icon: 'user') do %>
|
||||
<li><%= sidebar_item(admins_users_path, '用户列表', icon: 'user', controller: 'admins-users') %></li>
|
||||
<li><%= sidebar_item(admins_organizations_path, '组织列表', icon: 'user', controller: 'admins-organizations') %></li>
|
||||
<% end %>
|
||||
</li>
|
||||
<li>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Admins::OrganizationsController, type: :controller do
|
||||
|
||||
end
|
|
@ -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
|
Loading…
Reference in New Issue