diff --git a/.gitignore b/.gitignore index 4a01bd5e..2735825a 100644 --- a/.gitignore +++ b/.gitignore @@ -84,4 +84,5 @@ redis_data/ dump.rdb .tags* ceshi_user.xlsx -public/trace_task_results \ No newline at end of file +public/trace_task_results +public/项目活跃度排行.xls \ 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 c4f968da..bee024f8 100644 --- a/app/controllers/admins/projects_rank_controller.rb +++ b/app/controllers/admins/projects_rank_controller.rb @@ -1,16 +1,55 @@ class Admins::ProjectsRankController < Admins::BaseController - def index - @rank_date = rank_date - deleted_data = $redis_cache.smembers("v2-project-rank-deleted") - $redis_cache.zrem("v2-project-rank-#{rank_date}", deleted_data) unless deleted_data.blank? - @date_rank = $redis_cache.zrevrange("v2-project-rank-#{rank_date}", 0, -1, withscores: true) + @statistics = DailyProjectStatistic.where("date >= ? AND date <= ?", begin_date, end_date) + @statistics = @statistics.group(:project_id).select("project_id, + sum(score) as score, + sum(visits) as visits, + sum(watchers) as watchers, + sum(praises) as praises, + sum(forks) as forks, + sum(issues) as issues, + sum(pullrequests) as pullrequests, + sum(commits) as commits").includes(:project) + @statistics = @statistics.order("#{sort_by} #{sort_direction}") + export_excel(@statistics.limit(50)) end private - def rank_date - params.fetch(:date, Date.today.to_s) + def begin_date + params.fetch(:begin_date, Date.today.to_s) + end + + def end_date + params.fetch(:end_date, Date.today.to_s) + end + + def sort_by + DailyProjectStatistic.column_names.include?(params.fetch(:sort_by, "score")) ? params.fetch(:sort_by, "score") : "score" + end + + def sort_direction + %w(desc asc).include?(params.fetch(:sort_direction, "desc")) ? params.fetch(:sort_direction, "desc") : "desc" + end + + def export_excel(data) + book = Spreadsheet::Workbook.new + sheet = book.create_worksheet :name => "项目活跃度排行" + sheet.row(0).concat %w(排名 项目全称 项目地址 得分 访问数 关注数 点赞数 fork数 疑修数 合并请求数 提交数) + data.each_with_index do |d, index| + sheet[index+1,0] = index+1 + sheet[index+1,1] = "#{d&.project&.owner&.nickname}/#{d&.project&.name}" + sheet[index+1,2] = "#{Rails.application.config_for(:configuration)['platform_url']}/#{d&.project&.owner&.login}/#{d&.project&.identifier}" + sheet[index+1,3] = d.score + sheet[index+1,4] = d.visits + sheet[index+1,5] = d.watchers + sheet[index+1,6] = d.praises + sheet[index+1,7] = d.forks + sheet[index+1,8] = d.issues + sheet[index+1,9] = d.pullrequests + sheet[index+1,10] = d.commits + end + book.write "#{Rails.root}/public/项目活跃度排行.xls" end end \ No newline at end of file diff --git a/app/jobs/daily_project_statistics_job.rb b/app/jobs/daily_project_statistics_job.rb new file mode 100644 index 00000000..98506748 --- /dev/null +++ b/app/jobs/daily_project_statistics_job.rb @@ -0,0 +1,32 @@ +class DailyProjectStatisticsJob < ApplicationJob + queue_as :cache + + def perform + date = (Date.today - 1.days).to_s + daily_data_keys = $redis_cache.keys("v2-project-statistic:*-#{date}") + daily_data_keys.each do |key| + result = $redis_cache.hgetall(key) + project_id = key.gsub('v2-project-statistic:', '').gsub("-#{date}", '') + visits = result["visits"].to_i + watchers = result["watchers"].to_i + praises = result["praises"].to_i + forks = result["forks"].to_i + issues = result["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 + DailyProjectStatistic.create!( + project_id: project_id, + date: date, + score: score , + visits: visits, + watchers: watchers, + praises: praises, + forks: forks, + issues: issues, + pullrequests: pullrequests, + commits: commits + ) + end + end +end \ No newline at end of file diff --git a/app/models/daily_project_statistic.rb b/app/models/daily_project_statistic.rb new file mode 100644 index 00000000..f7fc0aad --- /dev/null +++ b/app/models/daily_project_statistic.rb @@ -0,0 +1,28 @@ +# == Schema Information +# +# 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 +# +# Indexes +# +# index_daily_project_statistics_on_date (date) +# index_daily_project_statistics_on_project_id (project_id) +# + +class DailyProjectStatistic < ApplicationRecord + + + belongs_to :project +end diff --git a/app/views/admins/projects_rank/index.html.erb b/app/views/admins/projects_rank/index.html.erb index d3a7926b..e9d38afa 100644 --- a/app/views/admins/projects_rank/index.html.erb +++ b/app/views/admins/projects_rank/index.html.erb @@ -5,70 +5,34 @@
<%= form_tag(admins_projects_rank_index_path, method: :get, class: 'form-inline search-form flex-1', id: 'project-rank-date-form') do %> -
- - <% dates_array = (0..30).to_a.map { |item| [(Date.today-item.days).to_s, (Date.today-item.days).to_s] } %> - <%= select_tag(:date, options_for_select(dates_array, params[:date]), class:"form-control",id: "project-rank-date-select")%> +
+ 开始日期 + +
+
+ 结束日期 +
<% end %> - + <%= link_to '导出', "/项目活跃度排行.xls", class: 'btn btn-primary mr-3' %>
-
- - - - - - - - - - - - - - - - - <% @date_rank.each_with_index do |item, index| %> - - - <% project_common = $redis_cache.hgetall("v2-project-common:#{item[0]}") %> - <% owner_common = $redis_cache.hgetall("v2-owner-common:#{project_common["owner_id"]}")%> - - - - <% project_date_statistic_key = "v2-project-statistic:#{item[0]}-#{@rank_date}"%> - <% if $redis_cache.exists(project_date_statistic_key)%> - <% visits = $redis_cache.hget(project_date_statistic_key, "visits") %> - - <% watchers = $redis_cache.hget(project_date_statistic_key, "watchers") %> - - <% praises = $redis_cache.hget(project_date_statistic_key, "praises") %> - - <% forks = $redis_cache.hget(project_date_statistic_key, "forks") %> - - <% issues = $redis_cache.hget(project_date_statistic_key, "issues") %> - - <% pullrequests = $redis_cache.hget(project_date_statistic_key, "pullrequests") %> - - <% commits = $redis_cache.hget(project_date_statistic_key, "commits") %> - - <% else %> - - <% end %> - - <% end %> - -
排名项目得分访问数关注数点赞数fork数疑修数合并请求数提交数
<%= index + 1%> - /<%= project_common["identifier"]%>"> - <%= "#{owner_common["name"]}/#{project_common["name"]}" %> - - <%= item[1] %><%= visits || 0 %><%= watchers || 0 %><%= praises || 0 %><%= forks || 0 %><%= issues || 0 %><%= pullrequests || 0 %><%= commits || 0 %>暂无数据
+
+ <%= render partial: 'admins/projects_rank/shared/data_list', locals: { statistics: @statistics } %>
\ No newline at end of file diff --git a/app/views/admins/projects_rank/index.js.erb b/app/views/admins/projects_rank/index.js.erb new file mode 100644 index 00000000..0d36dd86 --- /dev/null +++ b/app/views/admins/projects_rank/index.js.erb @@ -0,0 +1 @@ +$('.project-rank-list-container').html("<%= j( render partial: 'admins/projects_rank/shared/data_list', locals: { statistics: @statistics } ) %>"); \ No newline at end of file diff --git a/app/views/admins/projects_rank/shared/_data_list.html.erb b/app/views/admins/projects_rank/shared/_data_list.html.erb new file mode 100644 index 00000000..bb9f4577 --- /dev/null +++ b/app/views/admins/projects_rank/shared/_data_list.html.erb @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + <% statistics.each_with_index do |item, index| %> + + + + + + + + + + + + + + <% end %> + +
排名项目得分<%= sort_tag('访问数', name: 'visits', path: admins_projects_rank_index_path) %><%= sort_tag('关注数', name: 'watchers', path: admins_projects_rank_index_path) %><%= sort_tag('点赞数', name: 'praises', path: admins_projects_rank_index_path) %><%= sort_tag('fork数', name: 'forks', path: admins_projects_rank_index_path) %><%= sort_tag('疑修数', name: 'issues', path: admins_projects_rank_index_path) %><%= sort_tag('合并请求数', name: 'pullrequests', path: admins_projects_rank_index_path) %><%= sort_tag('提交数', name: 'commits', path: admins_projects_rank_index_path) %>
<%= index + 1%> + "> + <%= "#{item&.project&.owner&.nickname}/#{item&.project&.name}" %> + + <%= item&.score %><%= item&.visits %><%= item&.watchers %><%= item&.praises %><%= item&.forks %><%= item&.issues %><%= item&.pullrequests %><%= item&.commits %>
\ No newline at end of file diff --git a/app/views/admins/shared/_sidebar.html.erb b/app/views/admins/shared/_sidebar.html.erb index 813e2338..4db54507 100644 --- a/app/views/admins/shared/_sidebar.html.erb +++ b/app/views/admins/shared/_sidebar.html.erb @@ -13,13 +13,7 @@ diff --git a/config/sidekiq_cron.yml b/config/sidekiq_cron.yml index 448e9c94..0ec8f997 100644 --- a/config/sidekiq_cron.yml +++ b/config/sidekiq_cron.yml @@ -7,3 +7,8 @@ delay_expired_issue: cron: "0 0 * * *" class: "DelayExpiredIssueJob" queue: message + +create_daily_project_statistics: + cron: "0 1 * * *" + class: "DailyProjectStatisticsJob" + queue: cache \ No newline at end of file diff --git a/db/migrate/20231219020521_create_daily_project_statistics.rb b/db/migrate/20231219020521_create_daily_project_statistics.rb new file mode 100644 index 00000000..4465154d --- /dev/null +++ b/db/migrate/20231219020521_create_daily_project_statistics.rb @@ -0,0 +1,19 @@ +class CreateDailyProjectStatistics < ActiveRecord::Migration[5.2] + def change + create_table :daily_project_statistics do |t| + t.references :project + t.date :date + t.index :date + t.integer :score, default: 0 + t.integer :visits, default: 0 + t.integer :watchers, default: 0 + t.integer :praises, default: 0 + t.integer :forks, default: 0 + t.integer :issues, default: 0 + t.integer :pullrequests, default: 0 + t.integer :commits, default: 0 + + t.timestamps + end + end +end