diff --git a/app/controllers/admins/identity_verifications_controller.rb b/app/controllers/admins/identity_verifications_controller.rb index 26dc35d3f..1db1a9883 100644 --- a/app/controllers/admins/identity_verifications_controller.rb +++ b/app/controllers/admins/identity_verifications_controller.rb @@ -14,13 +14,14 @@ class Admins::IdentityVerificationsController < Admins::BaseController end def update - if @identity_verification.update(update_params) + if update_params[:state] == "已拒绝" && update_params[:description].blank? + flash[:danger] = '拒绝理由不能为空' + render 'edit' + else UserAction.create(action_id: @identity_verification.id, action_type: "UpdateIdentityVerifications", user_id: current_user.id, :ip => request.remote_ip, data_bank: @identity_verification.attributes.to_json) + @identity_verification.update(update_params) redirect_to admins_identity_verifications_path flash[:success] = "更新成功" - else - redirect_to admins_identity_verifications_path - flash[:danger] = "更新失败" end end diff --git a/app/controllers/admins/issues_rank_controller.rb b/app/controllers/admins/issues_rank_controller.rb new file mode 100644 index 000000000..79450fbfb --- /dev/null +++ b/app/controllers/admins/issues_rank_controller.rb @@ -0,0 +1,29 @@ +class Admins::IssuesRankController < Admins::BaseController + + def index + @statistics = DailyProjectStatistic.where('date >= ? AND date <= ?', begin_date, end_date) + @statistics = @statistics.group(:project_id).joins(:project).select("project_id, + sum(issues) as issues, + sum(closed_issues) as closed_issues, + projects.issues_count as issues_count") + @statistics = @statistics.order("#{sort_by} #{sort_direction}").limit(50) + end + + private + def begin_date + params.fetch(:begin_date, (Date.yesterday-7.days).to_s) + end + + def end_date + params.fetch(:end_date, Date.yesterday.to_s) + end + + def sort_by + DailyProjectStatistic.column_names.include?(params.fetch(:sort_by, "issues")) ? params.fetch(:sort_by, "issues") : "issues" + end + + def sort_direction + %w(desc asc).include?(params.fetch(:sort_direction, "desc")) ? params.fetch(:sort_direction, "desc") : "desc" + end + +end \ No newline at end of file diff --git a/app/controllers/admins/projects_rank_controller.rb b/app/controllers/admins/projects_rank_controller.rb index e4d8046e0..8db0961b7 100644 --- a/app/controllers/admins/projects_rank_controller.rb +++ b/app/controllers/admins/projects_rank_controller.rb @@ -17,11 +17,11 @@ class Admins::ProjectsRankController < Admins::BaseController private def begin_date - params.fetch(:begin_date, (Date.today-7.days).to_s) + params.fetch(:begin_date, (Date.yesterday-7.days).to_s) end def end_date - params.fetch(:end_date, Date.today.to_s) + params.fetch(:end_date, Date.yesterday.to_s) end def sort_by diff --git a/app/jobs/daily_project_statistics_job.rb b/app/jobs/daily_project_statistics_job.rb index ad606f137..3672d1924 100644 --- a/app/jobs/daily_project_statistics_job.rb +++ b/app/jobs/daily_project_statistics_job.rb @@ -13,6 +13,7 @@ class DailyProjectStatisticsJob < ApplicationJob praises = result["praises"].to_i forks = result["forks"].to_i issues = result["issues"].to_i + closed_issues = result["closed_issues"].to_i pullrequests = result["pullrequests"].to_i commits = result["commits"].to_i score = visits *1 + watchers *5 + praises * 5 + forks * 10 + issues *5 + pullrequests * 10 + commits * 5 @@ -25,6 +26,7 @@ class DailyProjectStatisticsJob < ApplicationJob praises: praises, forks: forks, issues: issues, + closed_issues: closed_issues, pullrequests: pullrequests, commits: commits ) diff --git a/app/models/daily_project_statistic.rb b/app/models/daily_project_statistic.rb index f7fc0aad7..ffe51bdb3 100644 --- a/app/models/daily_project_statistic.rb +++ b/app/models/daily_project_statistic.rb @@ -2,18 +2,20 @@ # # Table name: daily_project_statistics # -# id :integer not null, primary key -# project_id :integer -# date :string(255) -# visits :integer default("0") -# watchers :integer default("0") -# praises :integer default("0") -# forks :integer default("0") -# issues :integer default("0") -# pullrequests :integer default("0") -# commits :integer default("0") -# created_at :datetime not null -# updated_at :datetime not null +# id :integer not null, primary key +# project_id :integer +# date :date +# score :integer default("0") +# visits :integer default("0") +# watchers :integer default("0") +# praises :integer default("0") +# forks :integer default("0") +# issues :integer default("0") +# pullrequests :integer default("0") +# commits :integer default("0") +# created_at :datetime not null +# updated_at :datetime not null +# closed_issues :integer default("0") # # Indexes # diff --git a/app/models/issue.rb b/app/models/issue.rb index 1c82d7120..5e122c8aa 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -99,9 +99,20 @@ class Issue < ApplicationRecord scope :closed, ->{where(status_id: 5)} scope :opened, ->{where.not(status_id: 5)} after_create :incre_project_common, :incre_user_statistic, :incre_platform_statistic - after_save :change_versions_count, :send_update_message_to_notice_system, :associate_attachment_container + after_save :incre_or_decre_closed_issues_count, :change_versions_count, :send_update_message_to_notice_system, :associate_attachment_container after_destroy :update_closed_issues_count_in_project!, :decre_project_common, :decre_user_statistic, :decre_platform_statistic + def incre_or_decre_closed_issues_count + if previous_changes[:status_id].present? + if previous_changes[:status_id][1] == 5 + CacheAsyncSetJob.perform_later("project_common_service", {closed_issues: 1}, self.project_id) + end + if previous_changes[:status_id][0] == 5 + CacheAsyncSetJob.perform_later("project_common_service", {closed_issues: -1}, self.project_id) + end + end + end + def incre_project_common CacheAsyncSetJob.perform_later("project_common_service", {issues: 1}, self.project_id) end diff --git a/app/services/cache/v2/project_common_service.rb b/app/services/cache/v2/project_common_service.rb index 0d167c2a7..1e85f3e08 100644 --- a/app/services/cache/v2/project_common_service.rb +++ b/app/services/cache/v2/project_common_service.rb @@ -1,5 +1,5 @@ class Cache::V2::ProjectCommonService < ApplicationService - attr_reader :project_id, :owner_id, :name, :identifier, :description, :visits, :watchers, :praises, :forks, :issues, :pullrequests, :commits + attr_reader :project_id, :owner_id, :name, :identifier, :description, :visits, :watchers, :praises, :forks, :issues, :closed_issues, :pullrequests, :commits attr_accessor :project def initialize(project_id, params={}) @@ -13,6 +13,7 @@ class Cache::V2::ProjectCommonService < ApplicationService @praises = params[:praises] @forks = params[:forks] @issues = params[:issues] + @closed_issues = params[:closed_issues] @pullrequests = params[:pullrequests] @commits = params[:commits] end @@ -78,6 +79,10 @@ class Cache::V2::ProjectCommonService < ApplicationService "issues" end + def closed_issues_key + "closed_issues" + end + def pullrequests_key "pullrequests" end @@ -151,6 +156,10 @@ class Cache::V2::ProjectCommonService < ApplicationService Cache::V2::ProjectRankService.call(@project_id, {issues: @issues}) Cache::V2::ProjectDateRankService.call(@project_id, Date.today, {issues: @issues}) end + if @closed_issues.present? + $redis_cache.hincrby(project_common_key, closed_issues_key, @closed_issues) + Cache::V2::ProjectDateRankService.call(@project_id, Date.today, {closed_issues: @closed_issues}) + end if @pullrequests.present? $redis_cache.hincrby(project_common_key, pullrequests_key, @pullrequests) Cache::V2::ProjectRankService.call(@project_id, {pullrequests: @pullrequests}) @@ -202,6 +211,10 @@ class Cache::V2::ProjectCommonService < ApplicationService $redis_cache.hset(project_common_key, issues_key, Issue.issue_issue.where(project_id: @project_id).count) end + def reset_project_closed_issues + $redis_cache.hset(project_common_key, closed_issues_key, Issue.issue_issue.closed.where(project_id: @project_id).count) + end + def reset_project_pullrequests $redis_cache.hset(project_common_key, pullrequests_key, PullRequest.where(project_id: @project_id).count) end @@ -224,6 +237,7 @@ class Cache::V2::ProjectCommonService < ApplicationService reset_project_praises reset_project_forks reset_project_issues + reset_project_closed_issues reset_project_pullrequests reset_project_commits diff --git a/app/services/cache/v2/project_date_rank_service.rb b/app/services/cache/v2/project_date_rank_service.rb index 9df69bbb4..bf661f0a2 100644 --- a/app/services/cache/v2/project_date_rank_service.rb +++ b/app/services/cache/v2/project_date_rank_service.rb @@ -1,6 +1,6 @@ # 项目日活跃度计算存储 class Cache::V2::ProjectDateRankService < ApplicationService - attr_reader :project_id, :rank_date, :visits, :praises, :forks, :issues, :pullrequests, :commits + attr_reader :project_id, :rank_date, :visits, :praises, :forks, :issues, :closed_issues, :pullrequests, :commits attr_accessor :project_common def initialize(project_id, rank_date=Date.today, params={}) @@ -11,6 +11,7 @@ class Cache::V2::ProjectDateRankService < ApplicationService @praises = params[:praises] @forks = params[:forks] @issues = params[:issues] + @closed_issues = params[:closed_issues] @pullrequests = params[:pullrequests] @commits = params[:commits] end @@ -57,6 +58,9 @@ class Cache::V2::ProjectDateRankService < ApplicationService $redis_cache.zincrby(project_rank_key, @issues.to_i * 5, @project_id) $redis_cache.hincrby(project_rank_statistic_key, "issues", @issues.to_i) end + if @closed_issues.present? + $redis_cache.hincrby(project_rank_statistic_key, "closed_issues", @closed_issues.to_i) + end if @pullrequests.present? $redis_cache.zincrby(project_rank_key, @pullrequests.to_i * 10, @project_id) $redis_cache.hincrby(project_rank_statistic_key, "pullrequests", @pullrequests.to_i) diff --git a/app/views/admins/identity_verifications/edit.html.erb b/app/views/admins/identity_verifications/edit.html.erb index 580c86f3f..28289e74f 100644 --- a/app/views/admins/identity_verifications/edit.html.erb +++ b/app/views/admins/identity_verifications/edit.html.erb @@ -106,7 +106,7 @@
- <%= f.input :description, as: :text,label: '拒绝理由:(拒绝时请填写拒绝理由,可以为空)', wrapper_html: { class: 'col-md-12' }, input_html: { maxlength: 100, size: 40, class: 'col-md-11' , value: @identity_verification.description } %> + <%= f.input :description, as: :text,label: '拒绝理由:(拒绝时请填写拒绝理由,不可以为空)', wrapper_html: { class: 'col-md-12' }, input_html: { maxlength: 100, size: 40, class: 'col-md-11' , value: @identity_verification.description } %>
<%= f.button :submit, value: '保存', class: 'btn-primary mr-3 px-4' %> diff --git a/app/views/admins/issues_rank/index.html.erb b/app/views/admins/issues_rank/index.html.erb new file mode 100644 index 000000000..4fc56ada9 --- /dev/null +++ b/app/views/admins/issues_rank/index.html.erb @@ -0,0 +1,37 @@ +<% define_admin_breadcrumbs do %> + <% add_admin_breadcrumb('项目排行榜', admins_path) %> +<% end %> + + +
+ <%= form_tag(admins_issues_rank_index_path, method: :get, class: 'form-inline search-form flex-1', id: 'issue-rank-date-form') do %> +
+ 开始日期 + +
+
+ 截止日期 + +
+ <% end %> +
+ +
+ <%= render partial: 'admins/issues_rank/shared/data_list', locals: { statistics: @statistics } %> +
+ \ No newline at end of file diff --git a/app/views/admins/issues_rank/index.js.erb b/app/views/admins/issues_rank/index.js.erb new file mode 100644 index 000000000..189206df0 --- /dev/null +++ b/app/views/admins/issues_rank/index.js.erb @@ -0,0 +1 @@ +$('.issue-rank-list-container').html("<%= j( render partial: 'admins/issues_rank/shared/data_list', locals: { statistics: @statistics } ) %>"); \ No newline at end of file diff --git a/app/views/admins/issues_rank/shared/_data_list.html.erb b/app/views/admins/issues_rank/shared/_data_list.html.erb new file mode 100644 index 000000000..9512028c3 --- /dev/null +++ b/app/views/admins/issues_rank/shared/_data_list.html.erb @@ -0,0 +1,26 @@ + + + + + + + + + + + + <% statistics.each_with_index do |item, index| %> + + + + + + + + <% end %> + +
排名项目新增疑修数关闭疑修数当前疑修数量
<%= index + 1%> + "> + <%= "#{item&.project&.owner&.real_name}/#{item&.project&.name}" %> + + <%= item&.issues %><%= item&.closed_issues %><%= item&.project&.issues&.issue_issue.count %>
\ No newline at end of file diff --git a/app/views/admins/projects_rank/index.html.erb b/app/views/admins/projects_rank/index.html.erb index e8f334f05..2e33a5335 100644 --- a/app/views/admins/projects_rank/index.html.erb +++ b/app/views/admins/projects_rank/index.html.erb @@ -7,11 +7,11 @@ <%= form_tag(admins_projects_rank_index_path, method: :get, class: 'form-inline search-form flex-1', id: 'project-rank-date-form') do %>
开始日期 - +
截止日期 - +
<% end %> <%= link_to '导出', "/项目活跃度排行.xls", class: 'btn btn-primary mr-3' %> diff --git a/app/views/admins/shared/_sidebar.html.erb b/app/views/admins/shared/_sidebar.html.erb index 4db545074..f9bf9ae48 100644 --- a/app/views/admins/shared/_sidebar.html.erb +++ b/app/views/admins/shared/_sidebar.html.erb @@ -81,6 +81,7 @@ <%= sidebar_item_group('#rank-submenu', '活跃度排行', icon: 'calendar') do %>
  • <%= sidebar_item(admins_users_rank_index_path, '用户活跃度排行', icon: 'user', controller: 'admins-users_rank') %>
  • <%= sidebar_item(admins_projects_rank_index_path, '项目活跃度排行', icon: 'database', controller: 'admins-projects_rank') %>
  • +
  • <%= sidebar_item(admins_issues_rank_index_path, '疑修活跃度排行', icon: 'calendar', controller: 'admins-issues_rank') %>
  • <% end %> diff --git a/config/routes.rb b/config/routes.rb index 6138028d5..a165a3d1e 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -822,6 +822,7 @@ Rails.application.routes.draw do resources :identity_verifications resources :site_pages resources :page_themes + resources :issues_rank, only: [:index] resources :projects_rank, only: [:index] resources :sites resources :edu_settings diff --git a/db/migrate/202401321314371_add_closed_issues_to_daily_project_statistics.rb b/db/migrate/202401321314371_add_closed_issues_to_daily_project_statistics.rb new file mode 100644 index 000000000..2b38b18b0 --- /dev/null +++ b/db/migrate/202401321314371_add_closed_issues_to_daily_project_statistics.rb @@ -0,0 +1,5 @@ +class AddClosedIssuesToDailyProjectStatistics < ActiveRecord::Migration[5.2] + def change + add_column :daily_project_statistics, :closed_issues, :integer, default: 0 + end +end