| @@ -84,4 +84,5 @@ redis_data/ | |||
| dump.rdb | |||
| .tags* | |||
| ceshi_user.xlsx | |||
| public/trace_task_results | |||
| public/trace_task_results | |||
| public/项目活跃度排行.xls | |||
| @@ -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}" | |||
| end | |||
| rescue | |||
| @names_array = [] | |||
| def sort_by | |||
| params.fetch(:sort_by, "score") | |||
| end | |||
| 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 | |||
| @@ -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 | |||
| @@ -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 | |||
| @@ -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> | |||
| @@ -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 } ) %>"); | |||
| @@ -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> | |||
| @@ -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 | |||
| @@ -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 | |||