Compare commits

..

19 Commits

Author SHA1 Message Date
呱呱呱 74f928bab2 setting laboratory pm logo 2025-06-25 09:43:50 +08:00
yystopf 9cb7a22e52 fix: error返回 2025-06-24 14:21:33 +08:00
yystopf 6a7174781c 新增:重新打开pr接口 2025-06-23 19:27:47 +08:00
yystopf 880f547b3b 更改:继承模板 2025-06-21 15:42:57 +08:00
yystopf f97ad21af5 Merge branch 'standalone_develop' of https://gitlink.org.cn/Trustie/forgeplus into standalone_develop 2025-06-21 15:06:32 +08:00
yystopf 5230064b29 更改:解决加载过慢的问题以及child_count查询范围 2025-06-21 15:06:24 +08:00
xxq250 8fffa5530c Merge remote-tracking branch 'origin/standalone_develop' into standalone_develop 2025-06-21 08:33:30 +08:00
yystopf 02df11cc64 更改:导入工作项默认创建者 2025-06-21 08:33:10 +08:00
yystopf ba2a76de8c 更改:导入工作项默认创建者 2025-06-20 15:09:26 +08:00
yystopf f1bf41c7f6 更改 trend project可以为空 2025-06-20 15:07:45 +08:00
yystopf 1a282dc925 fix: 用户导入导出按钮隐藏 2025-06-20 13:58:32 +08:00
yystopf 829e6bfe02 更改:未拥有权限去除新增按钮 2025-06-20 11:22:10 +08:00
yystopf c3754f65cd 更改:运营人员菜单权限 2025-06-20 10:32:01 +08:00
yystopf 16a64027f1 更改:运营人员菜单权限 2025-06-20 10:29:22 +08:00
yystopf e6eea663a9 更改:运营人员菜单权限 2025-06-20 10:25:24 +08:00
KingChan 52b46f4b89 Merge pull request 'update' (#396) from KingChan/forgeplus:standalone_develop into standalone_develop 2025-06-19 16:46:10 +08:00
KingChan 831576d4aa Merge pull request 'admin端删除组织记录渲染组织信息' (#395) from KingChan/forgeplus:standalone_develop into standalone_develop 2025-06-19 16:39:34 +08:00
KingChan 76d3c29c42 Merge pull request '修复删除bug' (#394) from KingChan/forgeplus:standalone_develop into standalone_develop 2025-06-19 16:27:45 +08:00
KingChan 7496a4bdd6 Merge pull request '增加用户删除组织时创建记录' (#393) from KingChan/forgeplus:standalone_develop into standalone_develop 2025-06-19 16:24:35 +08:00
37 changed files with 303 additions and 43 deletions

View File

@ -1,4 +1,6 @@
class Admins::DashboardsController < Admins::BaseController
before_action :require_business
def index
# 用户活跃数
day_user_ids = CommitLog.where(created_at: today).pluck(:user_id).uniq

View File

@ -23,7 +23,7 @@ class Admins::LaboratorySettingsController < Admins::BaseController
def form_params
params.permit(:identifier, :name,
:nav_logo, :login_logo, :tab_logo, :oj_banner,
:nav_logo, :login_logo, :tab_logo, :pm_logo, :oj_banner,
:subject_banner, :course_banner, :competition_banner, :moop_cases_banner,
:footer, navbar: %i[name link hidden index])
end

View File

@ -1,5 +1,5 @@
class Admins::OrganizationsController < Admins::BaseController
before_action :require_admin
before_action :require_business
before_action :finder_org, except: [:index]
def index

View File

@ -1,5 +1,5 @@
class Admins::ProjectCategoriesController < Admins::BaseController
before_action :require_admin
before_action :require_business
before_action :get_category, only: [:edit,:update, :destroy]
before_action :validate_names, only: [:create, :update]

View File

@ -1,5 +1,5 @@
class Admins::ProjectIgnoresController < Admins::BaseController
before_action :require_admin
before_action :require_business
before_action :set_ignore, only: [:edit,:update, :destroy,:show]
# before_action :validate_params, only: [:create, :update]

View File

@ -1,5 +1,5 @@
class Admins::ProjectLanguagesController < Admins::BaseController
before_action :require_admin
before_action :require_business
before_action :get_language, only: [:edit,:update, :destroy]
before_action :validate_names, only: [:create, :update]

View File

@ -1,5 +1,5 @@
class Admins::ProjectLicensesController < Admins::BaseController
before_action :require_admin
before_action :require_business
before_action :set_license, only: [:edit,:update, :destroy,:show]
# before_action :validate_params, only: [:create, :update]

View File

@ -1,5 +1,5 @@
class Admins::ProjectsController < Admins::BaseController
before_action :require_admin
before_action :require_business
before_action :find_project, only: [:edit, :update]
def index

View File

@ -1,5 +1,5 @@
class Admins::UsersController < Admins::BaseController
before_action :require_admin
before_action :require_business
before_action :finder_user, except: [:index]
def index

View File

@ -177,7 +177,7 @@ class Api::Pm::IssuesController < Api::Pm::BaseController
issue.fake_id = row[0]
issue.subject = row[1]
issue.description = row[2]
author = User.find_by(login: row[3])
author = User.find_by(login: row[3]) || User.where(admin: true).first
issue.user = author
issue.created_on = row[4]
changer = User.find_by(login: row[5])

View File

@ -6,15 +6,15 @@ class Api::Pm::WeeklyIssuesController < Api::Pm::BaseController
@all_issues = Issue.joins(:issue_participants).where(issue_participants: {participant_id: params[:user_id], participant_type: ['assigned']})
@all_issues = @all_issues.where(enterprise_identifier: @enterprise_identifier, pm_issue_type: [1,2,3])
@this_week_all_issues = @all_issues.where("due_date >= ? and start_date <= ?", Date.today.beginning_of_week.to_s, Date.today.end_of_week.to_s).distinct
@this_week_all_issues = @this_week_all_issues.order('created_on desc')
@this_week_all_issues = @this_week_all_issues.order('created_on desc').pm_includes
@next_week_all_issues = @all_issues.where("due_date >= ? and start_date <=?", (Date.today.beginning_of_week+1.week).to_s, (Date.today.end_of_week+1.week).to_s).distinct
@next_week_all_issues = @next_week_all_issues.order('created_on desc')
@next_week_all_issues = @next_week_all_issues.order('created_on desc').pm_includes
@this_week_requirement_issues = @this_week_all_issues.where(pm_issue_type: 1)
@this_week_task_issues = @this_week_all_issues.where(pm_issue_type: 2)
@this_week_bug_issues = @this_week_all_issues.where(pm_issue_type: 3)
@close_requirement_issues = @this_week_requirement_issues.where(status_id: [3,5])
@close_task_issues = @this_week_task_issues.where(status_id: [3,5])
@close_bug_issues = @this_week_bug_issues.where(status_id: [3,5])
@close_requirement_issues = @this_week_requirement_issues.where(status_id: [3,5]).pm_includes
@close_task_issues = @this_week_task_issues.where(status_id: [3,5]).pm_includes
@close_bug_issues = @this_week_bug_issues.where(status_id: [3,5]).pm_includes
this_week_page = params[:this_week_page] || 1
this_week_limit = params[:this_week_limit] || 15
@this_week_all_issues = @this_week_all_issues.page(this_week_page).per(this_week_limit)
@ -69,7 +69,7 @@ class Api::Pm::WeeklyIssuesController < Api::Pm::BaseController
@all_issues = @all_issues.where(pm_project_id: params[:pm_project_ids].split(",")) if params[:pm_project_ids].present?
@all_issues = @all_issues.where(pm_issue_type: params[:pm_issue_type].to_i) if params[:pm_issue_type].present?
@this_week_all_issues = @all_issues.where("due_date >= ? and start_date <= ?", @weekly_begin_date, @weekly_end_date)
@this_week_all_issues = @this_week_all_issues.order('created_on desc')
@this_week_all_issues = @this_week_all_issues.order('created_on desc').pm_includes
@this_week_all_issues = kaminari_paginate(@this_week_all_issues)
end
def personal_issues
@ -86,9 +86,9 @@ class Api::Pm::WeeklyIssuesController < Api::Pm::BaseController
end
@all_issues = @all_issues.where(enterprise_identifier: @enterprise_identifier, pm_issue_type: [1,2,3])
@this_week_all_issues = @all_issues.where("due_date >= ? and start_date <= ?", @weekly_begin_date, @weekly_end_date).distinct
@this_week_all_issues = @this_week_all_issues.order('created_on desc')
@this_week_all_issues = @this_week_all_issues.order('created_on desc').pm_includes
@next_week_all_issues = @all_issues.where("due_date >= ? and start_date <=?", (@weekly_begin_date.to_date+1.week).to_s, (@weekly_end_date.to_date+1.week).to_s).distinct
@next_week_all_issues = @next_week_all_issues.order('created_on desc')
@next_week_all_issues = @next_week_all_issues.order('created_on desc').pm_includes
this_week_page = params[:this_week_page] || 1
this_week_limit = params[:this_week_limit] || 15
@this_week_all_issues = @this_week_all_issues.page(this_week_page).per(this_week_limit)

View File

@ -6,13 +6,22 @@ class Api::V1::Projects::Pulls::PullsController < Api::V1::BaseController
@pulls = kaminari_paginate(@pulls)
end
before_action :load_pull_request, only: [:show, :files]
before_action :load_pull_request, only: [:show, :reopen, :files]
def show
@result_object = Api::V1::Projects::Pulls::GetService.call(@project, @pull_request, current_user&.gitea_token)
@last_review = @pull_request.reviews.order(created_at: :desc).take
end
def reopen
@result_object = Api::V1::Projects::Pulls::ReopenService.call(@project, @pull_request, current_user)
if @result_object
render_ok
else
render_error("合并请求重新打开失败!")
end
end
def files
if params[:filepath].present?
@result_object = $gitea_hat_client.get_repos_pulls_files_by_owner_repo_index_filepath(@project&.owner.login, @project&.identifier, @pull_request.gitea_number, CGI.escape(params[:filepath]), {query: {token: current_user&.gitea_token}})

View File

@ -34,7 +34,9 @@ class LaboratorySetting < ApplicationRecord
def nav_logo_url
image_url('nav')
end
def pm_logo_url
image_url('pm_logo')
end
def tab_logo_url
image_url('tab')
end

View File

@ -22,7 +22,7 @@ class ProjectTrend < ApplicationRecord
CREATE = 'create'
MERGE = 'merge'
belongs_to :project
belongs_to :project, optional: true
belongs_to :trend, polymorphic: true, optional: true
belongs_to :user
end

View File

@ -144,6 +144,18 @@ class PullRequest < ApplicationRecord
"#{Rails.application.config_for(:configuration)['platform_url']}/#{self.project.owner.login}/#{self.project.name}/pulls/#{self.id}"
end
def closed?
self.status == CLOSED
end
def merged?
self.status == MERGED
end
def opened?
self.status == OPEN
end
def pr_status
case status
when 0

View File

@ -40,6 +40,7 @@ class Admins::SaveLaboratorySettingService < ApplicationService
save_image_file(params[:nav_logo], 'nav')
save_image_file(params[:login_logo], 'login')
save_image_file(params[:tab_logo], 'tab')
save_image_file(params[:pm_logo], 'pm_logo')
save_image_file(params[:subject_banner], '_subject_banner')
save_image_file(params[:course_banner], '_course_banner')
save_image_file(params[:competition_banner], '_competition_banner')

View File

@ -0,0 +1,39 @@
class Api::V1::Projects::Pulls::ReopenService < ApplicationService
include ActiveModel::Model
attr_reader :project, :pull_request, :issue, :user
def initialize(project, pull_request, user)
@project = project
@pull_request = pull_request
@issue = pull_request&.issue
@user = user
end
def call
raise Error, "参数错误" unless valid?
if gitea_change_status
@pull_request.update_column(:status, PullRequest::OPEN)
@pull_request&.project_trends&.where(action_type: ProjectTrend::CLOSE).destroy_all
@issue.update_column(:status_id, IssueStatus::ADD)
return true
else
raise Error, 'gitea change status failed'
end
end
private
def valid?
return false if @project.blank? || @pull_request.blank? || @issue.blank? || @user.blank?
return false unless @pull_request.closed?
return true
end
def gitea_change_status
gitea_result = Gitea::PullRequest::ChangeStatusService.call(@project.owner.login, @project.identifier, @pull_request.gitea_number, false, @user&.gitea_token)
return true if gitea_result[:status] == :success
return false
end
end

View File

@ -0,0 +1,38 @@
# Get a pull request
class Gitea::PullRequest::ChangeStatusService < Gitea::ClientService
attr_reader :owner, :repo, :number, :is_closed, :token
#eq:
# Gitea::PullRequest::ChangeStatusService.call(user.login, repository.identifier, pull.gitea_number, true, user.gitea_token)
def initialize(owner, repo, number, is_closed, token=nil)
@owner = owner
@repo = repo
@number = number
@is_closed = is_closed
@token = token
end
def call
response = get(url, request_params, true)
status, message, body = render_response(response)
json_format(status, message, body)
end
private
def request_params
Hash.new.merge(token: token, is_closed: is_closed)
end
def url
"/repos/#{owner}/#{repo}/pulls/#{number}/change_status".freeze
end
def json_format(status, message, body)
case status
when 204 then success(body)
else
error(message, status)
end
end
end

View File

@ -42,7 +42,7 @@
<div class="setting-item-head"><h6>Logo设置</h6></div>
<div class="dropdown-divider"></div>
<div class="pl-0 py-3 row setting-item-body">
<div class="col-12 col-md-4 logo-item">
<div class="col-12 col-md-3 logo-item">
<% nav_logo_img = setting.nav_logo_url %>
<div class="logo-item-left mr-3 <%= nav_logo_img ? 'has-img' : '' %>">
<img class="logo-item-img nav-logo-img" src="<%= nav_logo_img %>" style="<%= nav_logo_img.present? ? '' : 'display: none' %>"/>
@ -56,7 +56,7 @@
</div>
</div>
<div class="col-12 col-md-4 logo-item">
<div class="col-12 col-md-3 logo-item">
<% login_logo_img = setting.login_logo_url %>
<div class="logo-item-left mr-3 <%= login_logo_img ? 'has-img' : '' %>">
<img class="logo-item-img login-logo-img" src="<%= login_logo_img %>" style="<%= login_logo_img.present? ? '' : 'display: none' %>"/>
@ -70,7 +70,7 @@
</div>
</div>
<div class="col-12 col-md-4 logo-item">
<div class="col-12 col-md-3 logo-item">
<% tab_logo_img = setting.tab_logo_url %>
<div class="logo-item-left mr-3 <%= tab_logo_img ? 'has-img' : '' %>">
<img class="logo-item-img tab-logo-img" src="<%= tab_logo_img %>" style="<%= tab_logo_img.present? ? '' : 'display: none' %>"/>
@ -83,6 +83,21 @@
<div>尺寸16*16 32*32 48*48 64*64 </div>
</div>
</div>
<div class="col-12 col-md-3 logo-item">
<% pm_logo_img = setting.pm_logo_url %>
<div class="logo-item-left mr-3 <%= pm_logo_img ? 'has-img' : '' %>">
<img class="logo-item-img tab-logo-img" src="<%= pm_logo_img %>" style="<%= tab_logo_img.present? ? '' : 'display: none' %>"/>
<%= file_field_tag(:pm_logo, accept: 'image/png,image/jpg,image/jpeg', style: 'display: none', value: params[:pm_logo]) %>
<label for="pm_logo" class="logo-item-upload" data-toggle="tooltip" data-title="选择图片"></label>
</div>
<div class="logo-item-right">
<div class="logo-item-title flex-1">PM管理端logo</div>
<div>格式PNG、JPG</div>
<div>尺寸高度90px以内宽等比例缩放</div>
</div>
</div>
</div>
</div>

View File

@ -27,6 +27,7 @@
<td><%= link_to org.organization_users_count, "/#{org.login}", target: "_blank" %></td>
<td><%= link_to org.projects_count, "/#{org.login}", target: "_blank" %></td>
<td class="action-container">
<% if current_user.admin? %>
<%= javascript_void_link '开通CLA', class: 'action open-cla-action', data: { id: org.id }, style: org.open_cla? ? 'display: none;' : '' %>
<%= javascript_void_link '关闭CLA', class: 'action close-cla-action', data: { id: org.id }, style: org.open_cla? ? '' : 'display: none;' %>
<%= link_to '查看', admins_organization_path(org), class: 'action' %>
@ -36,6 +37,7 @@
<%= delete_link '删除', admins_organization_path(org, element: ".user-item-#{org.id}"), class: 'dropdown-item delete-user-action' %>
</div>
</div>
<% end %>
</td>
</tr>
<% end %>

View File

@ -25,8 +25,10 @@
<td><%= project_category.projects.select(:id).where(is_pinned: true).size %></td>
<td><%= project_category.created_at&.strftime('%Y-%m-%d %H:%M') %></td>
<td class="action-container">
<% if current_user.admin? %>
<%= link_to "编辑", edit_admins_project_category_path(project_category), remote: true, class: "action" %>
<%= link_to "删除", admins_project_category_path(project_category), method: :delete, data:{confirm: "确认删除的吗?"}, class: "action" %>
<% end %>
</td>
</tr>
<% end %>

View File

@ -8,7 +8,9 @@
<%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %>
<input type="reset" class="btn btn-secondary clear-btn" value="清空"/>
<% end %>
<% if current_user.admin? %>
<%= link_to "新增", new_admins_project_category_path, remote: true, class: "btn btn-primary pull-right", "data-disabled-with":"...新增" %>
<% end%>
</div>
<div class="box admin-list-container project-category-list-container">

View File

@ -31,8 +31,10 @@
=end%>
<td><%= project_ignore.created_at&.strftime('%Y-%m-%d %H:%M') %></td>
<td class="action-container">
<% if current_user.admin? %>
<%= link_to "编辑", edit_admins_project_ignore_path(project_ignore),remote: true, class: "action" %>
<%= link_to "删除", admins_project_ignore_path(project_ignore), method: :delete, data:{confirm: "确认删除的吗?"}, class: "action" %>
<% end %>
</td>
</tr>
<% end %>

View File

@ -8,7 +8,10 @@
<%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %>
<input type="reset" class="btn btn-secondary clear-btn" value="清空"/>
<% end %>
<% if current_user.admin? %>
<%= link_to "新增", new_admins_project_ignore_path, remote: true, class: "btn btn-primary pull-right", "data-disabled-with":"...新增" %>
<% end %>
</div>
</div>
<div class="box admin-list-container project-ignore-list-container">

View File

@ -19,8 +19,10 @@
<td><%= project_language.projects_count %></td>
<td><%= project_language.created_at&.strftime('%Y-%m-%d %H:%M') %></td>
<td class="action-container">
<% if current_user.admin? %>
<%= link_to "编辑", edit_admins_project_language_path(project_language), remote: true, class: "action" %>
<%= link_to "删除", admins_project_language_path(project_language), method: :delete, data:{confirm: "确认删除的吗?"}, class: "action" %>
<% end %>
</td>
</tr>
<% end %>

View File

@ -8,7 +8,9 @@
<%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %>
<input type="reset" class="btn btn-secondary clear-btn" value="清空"/>
<% end %>
<% if current_user.admin? %>
<%= link_to "新增", new_admins_project_language_path, remote: true, class: "btn btn-primary pull-right", "data-disabled-with":"...新增" %>
<% end%>
</div>
<div class="box admin-list-container project-language-list-container">

View File

@ -33,8 +33,10 @@
=end%>
<td><%= project_license.created_at&.strftime('%Y-%m-%d %H:%M') %></td>
<td class="action-container">
<% if current_user.admin? %>
<%= link_to "编辑", edit_admins_project_license_path(project_license),remote: true, class: "action" %>
<%= link_to "删除", admins_project_license_path(project_license), method: :delete, data:{confirm: "确认删除的吗?"}, class: "action" %>
<% end %>
</td>
</tr>
<% end %>

View File

@ -8,7 +8,9 @@
<%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %>
<input type="reset" class="btn btn-secondary clear-btn" value="清空"/>
<% end %>
<% if current_user.admin? %>
<%= link_to "新增", new_admins_project_license_path, remote: true, class: "btn btn-primary pull-right", "data-disabled-with":"...新增" %>
<% end %>
</div>
<div class="box admin-list-container project-license-list-container">

View File

@ -37,12 +37,14 @@
</td>
<td><%= project.created_on&.strftime('%Y-%m-%d %H:%M') %></td>
<td class="action-container">
<% if current_user.admin? %>
<% 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" %>
<% end %>
</td>
</tr>
<% end %>

View File

@ -0,0 +1,63 @@
<% sidebar_collapse = request.cookies['admin_sidebar_collapse'].to_s == 'true' %>
<nav id="sidebar" class="<%= sidebar_collapse ? 'active' : '' %>" data-current-controller="<%= admin_sidebar_controller %>">
<div class="sidebar-header">
<a href="/" class="sidebar-header-logo" data-toggle="tooltip" data-title="返回主站" >
<!-- <img class="rounded-circle" src="/images/<%#= url_to_avatar(current_user) %>" />-->
<span class="logo-label">后台管理</span>
</a>
<div id="sidebarCollapse" class="navbar-btn <%= sidebar_collapse ? 'active' : '' %>">
<i class="fa fa-chevron-left fold" data-toggle="tooltip" data-placement="right" data-boundary="window" title="收起"></i>
<i class="fa fa-bars unfold" data-toggle="tooltip" data-placement="right" data-boundary="window" title="展开"></i>
</div>
</div>
<!-- Sidebar Links -->
<ul class="list-unstyled components">
<li><%= sidebar_item(admins_path, '数据概览', icon: 'dashboard', controller: 'admins-dashboards', has_permission: current_user.admin? || current_user.business?) %></li>
<li>
<%= sidebar_item_group('#user-submenu', '用户', icon: 'user', has_permission: current_user.admin? || current_user.business?) do %>
<li><%= sidebar_item(admins_users_path, '用户列表', icon: 'user', controller: 'admins-users', has_permission: current_user.admin? || current_user.business?) %></li>
<li><%= sidebar_item(admins_organizations_path, '组织列表', icon: 'user', controller: 'admins-organizations', has_permission: current_user.admin? || current_user.business?) %></li>
<% end %>
</li>
<li>
<%= sidebar_item_group('#setting-submenu', '用户支持', icon: 'cogs', has_permission: current_user.admin?) do %>
<li><%= sidebar_item(admins_faqs_path, 'FAQ', icon: 'question-circle', controller: 'admins-faqs', has_permission: current_user.admin?) %></li>
<li><%= sidebar_item(admins_nps_path, 'NPS用户调研', icon: 'question-circle', controller: 'admins-nps', has_permission: current_user.admin?) %></li>
<li><%= sidebar_item(admins_feedbacks_path, '用户反馈', icon: 'question-circle', controller: 'admins-feedbacks', has_permission: current_user.admin?) %></li>
<li><%= sidebar_item(admins_user_actions_path, '操作记录', icon: 'pencil-square', controller: 'admins-user_actions', has_permission: current_user.admin?) %></li>
<li><%= sidebar_item(admins_system_notifications_path, '系统公告配置', icon: 'bell', controller: 'admins-system_notifications', has_permission: current_user.admin?) %></li>
<% end %>
</li>
<li><%= sidebar_item(admins_laboratories_path, '导航栏配置', icon: 'cloud', controller: 'admins-laboratories', has_permission: current_user.admin?) %></li>
<li>
<%= sidebar_item_group('#setting-system', '开发者配置', icon: 'wrench', has_permission: current_user.admin?) do %>
<li><%= sidebar_item(admins_sites_path, 'setting接口配置', icon: 'deaf', controller: 'admins-sites', has_permission: current_user.admin?) %></li>
<li><%= sidebar_item(admins_edu_settings_path, '全局变量配置', icon: 'pencil-square', controller: 'admins-edu_settings', has_permission: current_user.admin?) %></li>
<li><%= sidebar_item(admins_message_templates_path, '消息模版配置', icon: 'folder', controller: 'admins-message_templates', has_permission: current_user.admin?) %></li>
<% end %>
</li>
<li><%= sidebar_item(admins_reversed_keywords_path, '禁用词管理', icon: 'key', controller: 'admins-reversed_keywords', has_permission: current_user.admin?) %></li>
<li>
<%= sidebar_item_group('#projects-submenu', '开源项目', icon: 'database', has_permission: current_user.admin? || current_user.business?) do %>
<li><%= sidebar_item(admins_projects_path, '项目列表', icon: 'database', controller: 'admins-projects', has_permission: current_user.admin? || current_user.business?) %></li>
<li><%= sidebar_item(admins_project_languages_path, '项目语言', icon: 'language', controller: 'admins-project_languages', has_permission: current_user.admin? || current_user.business?) %></li>
<li><%= sidebar_item(admins_project_categories_path, '分类列表', icon: 'sitemap', controller: 'admins-project_categories', has_permission: current_user.admin? || current_user.business?) %></li>
<li><%= sidebar_item(admins_project_licenses_path, '开源许可证', icon: 'file-text-o', controller: 'admins-project_licenses', has_permission: current_user.admin? || current_user.business?) %></li>
<li><%= sidebar_item(admins_project_ignores_path, '忽略文件', icon: 'git', controller: 'admins-project_ignores', has_permission: current_user.admin? || current_user.business?) %></li>
<% end %>
</li>
<li>
<%= sidebar_item_group('#rank-submenu', '活跃度排行', icon: 'calendar', has_permission: current_user.admin?) do %>
<li><%= sidebar_item(admins_users_rank_index_path, '用户活跃度排行', icon: 'user', controller: 'admins-users_rank', has_permission: current_user.admin?) %></li>
<li><%= sidebar_item(admins_projects_rank_index_path, '项目活跃度排行', icon: 'database', controller: 'admins-projects_rank', has_permission: current_user.admin?) %></li>
<li><%= sidebar_item(admins_issues_rank_index_path, '疑修活跃度排行', icon: 'calendar', controller: 'admins-issues_rank', has_permission: current_user.admin?) %></li>
<% end %>
</li>
<li><%= sidebar_item('/', '返回主站', icon: 'sign-out', controller: 'root', has_permission: current_user.admin?) %></li>
</ul>
</nav>

View File

@ -27,11 +27,11 @@
<%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %>
<% end %>
<% if current_user.admin? %>
<%= link_to '下载导入模板', "/导入用户模板.xlsx", class: 'btn btn-secondary mr-3' %>
<%= javascript_void_link '导入用户', class: 'btn btn-secondary', data: { toggle: 'modal', target: '.admin-import-user-modal'} %>
<% end %>
</div>
<div class="box admin-list-container users-list-container">

View File

@ -27,26 +27,28 @@
<td><%= display_text(user.last_login_on&.strftime('%Y-%m-%d %H:%M')) %></td>
<td><%= link_to user.projects_count, "/#{user.login}/projects", target: "_blank" %></td>
<td class="action-container">
<%= link_to '编辑', edit_admins_user_path(user), class: 'action' %>
<% if current_user.admin? %>
<%= link_to '编辑', edit_admins_user_path(user), class: 'action' %>
<%= javascript_void_link '解锁', class: 'action unlock-action', data: { id: user.id }, style: user.locked? ? '' : 'display: none;' %>
<%= javascript_void_link '解锁', class: 'action unlock-action', data: { id: user.id }, style: user.locked? ? '' : 'display: none;' %>
<% if user.registered? %>
<%= javascript_void_link '激活', class: 'action active-action', data: { id: user.id } %>
<% end %>
<% if user.registered? %>
<%= javascript_void_link '激活', class: 'action active-action', data: { id: user.id } %>
<% end %>
<% if user.id != current_user.id %>
<%= javascript_void_link '加锁', class: 'action lock-action', data: { id: user.id }, style: user.locked? || user.registered? ? 'display: none;' : '' %>
<% end %>
<% if user.id != current_user.id %>
<%= javascript_void_link '加锁', class: 'action lock-action', data: { id: user.id }, style: user.locked? || user.registered? ? 'display: none;' : '' %>
<% end %>
<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">
<%= javascript_void_link '恢复禁密账号', class: 'dropdown-item reset-login-times-action', data: { id: user.id } %>
<%= javascript_void_link '重置Gitea Token', class: 'dropdown-item fresh-gitea-token-action', data: { id: user.id } %>
<%= delete_link '删除', admins_user_path(user, element: ".user-item-#{user.id}"), class: 'dropdown-item delete-user-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">
<%= javascript_void_link '恢复禁密账号', class: 'dropdown-item reset-login-times-action', data: { id: user.id } %>
<%= javascript_void_link '重置Gitea Token', class: 'dropdown-item fresh-gitea-token-action', data: { id: user.id } %>
<%= delete_link '删除', admins_user_path(user, element: ".user-item-#{user.id}"), class: 'dropdown-item delete-user-action' %>
</div>
</div>
</div>
<% end %>
</td>
</tr>
<% end %>

View File

@ -0,0 +1,55 @@
json.(issue, :id, :subject, :project_issues_index)
json.blockchain_token_num (Site.has_blockchain? && issue.project&.use_blockchain) ? issue.blockchain_token_num : nil
json.created_at issue.created_on.strftime("%Y-%m-%d %H:%M")
json.updated_at issue.updated_on.strftime("%Y-%m-%d %H:%M")
json.tags issue.show_issue_tags.each do |tag|
json.partial! "api/v1/issues/issue_tags/simple_detail", locals: {tag: tag}
end
json.status_name issue.issue_status&.name
json.status_id issue.status_id
json.status do
if issue.issue_status.present?
json.partial! "api/v1/issues/statues/simple_detail", locals: {status: issue.issue_status}
else
json.nil!
end
end
json.priority_name issue.priority&.name
json.priority_id issue.priority_id
json.priority do
if issue.priority.present?
json.partial! "api/v1/issues/issue_priorities/simple_detail", locals: {priority: issue.priority}
else
json.nil!
end
end
json.milestone_name issue.version&.name
json.milestone_id issue.fixed_version_id
json.root_id issue.root_id
json.pm_issue_type issue.pm_issue_type
json.pm_sprint_id issue.pm_sprint_id
json.pm_project_id issue.pm_project_id
json.time_scale issue.time_scale
if weekly_begin_date.present? && weekly_end_date.present?
if params[:pm_issue_types].present?
json.child_count issue.children_issues.where(pm_issue_type: 4).where("due_date >=? and start_date <=?", weekly_begin_date, weekly_end_date).count
else
json.child_count issue.children_issues.where("due_date >=? and start_date <=?", weekly_begin_date, weekly_end_date).count
end
else
if params[:pm_issue_types].present?
json.child_count issue.children_issues.where(pm_issue_type: 4).count
else
json.child_count issue.child_count
end
end
json.author do
json.partial! "api/v1/users/simple_user", locals: {user: issue.user}
end
json.assigners issue.show_assigners.each do |assigner|
json.partial! "api/v1/users/simple_user", locals: {user: assigner}
end
json.comment_journals_count issue.comment_journals.size
json.start_date issue.start_date
json.due_date issue.due_date

View File

@ -1,8 +1,8 @@
json.this_week_all_issues @this_week_all_issues.each do |issue|
json.partial! "api/v1/issues/simple_detail", locals: {issue: issue}
json.partial! "api/pm/weekly_issues/simple_detail", locals: {issue: issue, weekly_begin_date: @weekly_begin_date, weekly_end_date: @weekly_end_date}
end
json.this_week_total_count @this_week_all_issues.total_count
json.next_week_all_issues @next_week_all_issues.each do |issue|
json.partial! "api/v1/issues/simple_detail", locals: {issue: issue}
json.partial! "api/pm/weekly_issues/simple_detail", locals: {issue: issue, weekly_begin_date: @weekly_begin_date+1.week, weekly_end_date: @weekly_end_date+1.week}
end
json.next_week_total_count @next_week_all_issues.total_count

View File

@ -35,7 +35,6 @@ if params[:pm_issue_types].present?
else
json.child_count issue.child_count
end
json.author do
json.partial! "api/v1/users/simple_user", locals: {user: issue.user}
end

View File

@ -7,6 +7,7 @@ json.commits_count @gitea_pull["commit_num"]
json.files_count @gitea_pull["changed_files"]
json.comments_count @issue.journals.parent_journals.size
json.comments_total_count @issue.get_journals_size
json.can_reopen @pull_request.closed?
json.assign_user do
json.partial! 'users/user_simple', user: @issue_assign_to
end

View File

@ -203,6 +203,7 @@ defaults format: :json do
resources :pulls, module: 'pulls' do
member do
get :files
post :reopen
end
resources :versions, only: [:index] do
member do