更改:项目排行榜使用数据存储以及数据导出的功能

This commit is contained in:
yystopf 2023-12-19 14:57:54 +08:00
parent 016a2f8cf5
commit 21f559f254
9 changed files with 153 additions and 86 deletions

1
.gitignore vendored
View File

@ -85,3 +85,4 @@ dump.rdb
.tags*
ceshi_user.xlsx
public/trace_task_results
public/项目活跃度排行.xls

View File

@ -1,56 +1,17 @@
class Admins::ProjectsRankController < Admins::BaseController
before_action :get_timeable_key_names, only:[:index]
def index
puts @names_array
unless @names_array.blank?
$redis_cache.zunionstore("admin-days-project-rank", @names_array)
deleted_data = $redis_cache.smembers("v2-project-rank-deleted")
$redis_cache.zrem("admin-days-project-rank", deleted_data) unless deleted_data.blank?
@date_rank = $redis_cache.zrevrange("admin-days-project-rank", 0, -1, withscores: true)
@date_rank = @date_rank.map do |i|
visits = 0
watchers = 0
praises = 0
forks = 0
issues = 0
pullrequests = 0
commits = 0
(begin_date..end_date).to_a.each do |d|
result = $redis_cache.hgetall("v2-project-statistic:#{i[0]}-#{d}")
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
end
i + [visits,watchers,praises,forks,issues,pullrequests,commits]
end
case params[:sort_by]
when 'visits'
@date_rank = @date_rank.sort{|i| i[2]}
when 'watchers'
@date_rank = @date_rank.sort{|i| i[3]}
when 'praises'
@date_rank = @date_rank.sort{|i| i[4]}
when 'forks'
@date_rank = @date_rank.sort{|i| i[5]}
when 'issues'
@date_rank = @date_rank.sort{|i| i[6]}
when 'pullrequests'
@date_rank = @date_rank.sort{|i| i[7]}
when 'commits'
@date_rank = @date_rank.sort{|i| i[8]}
else
@date_rank = @date_rank.sort{|i| i[1]}
end
if params[:sort_direction].blank? || params[:sort_direction].to_s.downcase == "desc"
@date_rank = @date_rank.reverse
end
else
@date_rank = []
end
@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
@ -63,15 +24,32 @@ class Admins::ProjectsRankController < Admins::BaseController
params.fetch(:end_date, Date.today.to_s)
end
def get_timeable_key_names
begin
@names_array = []
(begin_date..end_date).to_a.each do |i|
@names_array << "v2-project-rank-#{i}"
def sort_by
params.fetch(:sort_by, "score")
end
rescue
@names_array = []
def sort_direction
params.fetch(:sort_direction, "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

View File

@ -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

View File

@ -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

View File

@ -5,28 +5,34 @@
<div class="box search-form-container user-list-form">
<%= form_tag(admins_projects_rank_index_path, method: :get, class: 'form-inline search-form flex-1', id: 'project-rank-date-form') do %>
<div class="form-group mr-2">
<label for="status">开始日期:</label>
<% dates_array = (0..30).to_a.map { |item| [(Date.today-item.days).to_s, (Date.today-item.days).to_s] } %>
<%= select_tag(:begin_date, options_for_select(dates_array, params[:begin_date]), class:"form-control",id: "project-rank-begin-date-select")%>
<div class="input-group">
<span class="input-group-text">开始日期</span>
<input class="form-control datetimepicker" type="text" name="begin_date" value="<%= params[:begin_date] || Date.today.to_s%>" aria-label="选择日期">
</div>
<div class="form-group mr-2">
<label for="status">截止日期:</label>
<% dates_array = (0..30).to_a.map { |item| [(Date.today-item.days).to_s, (Date.today-item.days).to_s] } %>
<%= select_tag(:end_date, options_for_select(dates_array, params[:end_date]), class:"form-control",id: "project-rank-end-date-select")%>
<div class="input-group">
<span class="input-group-text">结束日期</span>
<input class="form-control datetimepicker" type="text" name="end_date" value="<%= params[:end_date] || Date.today.to_s%>" aria-label="选择日期">
</div>
<% end %>
<%= link_to '导出', "/项目活跃度排行.xls", class: 'btn btn-primary mr-3' %>
</div>
<div class="box admin-list-container project-rank-list-container">
<%= render partial: 'admins/projects_rank/shared/data_list', locals: { date_rank: @date_rank } %>
<%= render partial: 'admins/projects_rank/shared/data_list', locals: { statistics: @statistics } %>
</div>
<script>
$("#project-rank-begin-date-select").on('change', function() {
$(".datetimepicker").on('change', function() {
$("#project-rank-date-form").submit()
});
$("#project-rank-end-date-select").on('change', function() {
$(".datetimepicker").on('change', function() {
$("#project-rank-date-form").submit()
});
$('.datetimepicker').datetimepicker({
language: 'zh-CN', // 中文语言包
autoclose: 1, // 选中日期后自动关闭
format: 'yyyy-mm-dd', // 日期格式
minView: "month", // 最小日期显示单元,这里最小显示月份界面,即可以选择到日
todayBtn: 1, // 显示今天按钮
todayHighlight: 1, // 显示今天高亮
});
</script>

View File

@ -1 +1 @@
$('.project-rank-list-container').html("<%= j( render partial: 'admins/projects_rank/shared/data_list', locals: { date_rank: @date_rank } ) %>");
$('.project-rank-list-container').html("<%= j( render partial: 'admins/projects_rank/shared/data_list', locals: { statistics: @statistics } ) %>");

View File

@ -14,25 +14,23 @@
</tr>
</thead>
<tbody>
<% date_rank.each_with_index do |item, index| %>
<% statistics.each_with_index do |item, index| %>
<tr class="">
<td><%= index + 1%></td>
<% project_common = $redis_cache.hgetall("v2-project-common:#{item[0]}") %>
<% owner_common = $redis_cache.hgetall("v2-owner-common:#{project_common["owner_id"]}")%>
<td>
<a href="/<%= owner_common["login"] %>/<%= project_common["identifier"]%>">
<%= "#{owner_common["name"]}/#{project_common["name"]}" %>
<a href="<%= "/#{item&.project&.owner&.login}/#{item&.project&.identifier}"%>">
<%= "#{item&.project&.owner&.nickname}/#{item&.project&.name}" %>
</a>
</td>
<td><%= item[1] %></td>
<td><%= item[2] %></td>
<td><%= item[3] %></td>
<td><%= item[4] %></td>
<td><%= item[5] %></td>
<td><%= item[6] %></td>
<td><%= item[7] %></td>
<td><%= item[8] %></td>
<td><%= item&.score %></td>
<td><%= item&.visits %></td>
<td><%= item&.watchers %></td>
<td><%= item&.praises %></td>
<td><%= item&.forks %></td>
<td><%= item&.issues %></td>
<td><%= item&.pullrequests %></td>
<td><%= item&.commits %></td>
</tr>
<% end %>
</tbody>

View File

@ -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

View File

@ -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