Merge branch 'pre_trustie_server' into trustie_server

This commit is contained in:
yystopf 2023-12-22 14:00:36 +08:00
commit beb96c5526
32 changed files with 495 additions and 179 deletions

5
.gitignore vendored
View File

@ -10,7 +10,7 @@
# Ignore lock config file
*.log
.env
# mac
*.DS_Store
.bashrc
@ -84,4 +84,5 @@ redis_data/
dump.rdb
.tags*
ceshi_user.xlsx
public/trace_task_results
public/trace_task_results
public/项目活跃度排行.xls

View File

@ -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-7.days).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&.real_name}/#{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

@ -25,7 +25,7 @@ class Admins::SystemNotificationsController < Admins::BaseController
@notification = SystemNotification.new(notification_params)
if @notification.save
redirect_to admins_system_notifications_path
flash[:success] = '系统消息创建成功'
flash[:success] = '系统公告创建成功'
else
redirect_to admins_system_notifications_path
flash[:danger] = @notification.errors.full_messages.join(",")
@ -37,7 +37,7 @@ class Admins::SystemNotificationsController < Admins::BaseController
if @notification.update_attributes(notification_params)
format.html do
redirect_to admins_system_notifications_path
flash[:success] = '系统消息更新成功'
flash[:success] = '系统公告更新成功'
end
format.js {render_ok}
else
@ -53,10 +53,10 @@ class Admins::SystemNotificationsController < Admins::BaseController
def destroy
if @notification.destroy
redirect_to admins_system_notifications_path
flash[:success] = "系统消息删除成功"
flash[:success] = "系统公告删除成功"
else
redirect_to admins_system_notifications_path
flash[:danger] = "系统消息删除失败"
flash[:danger] = "系统公告删除失败"
end
end

View File

@ -17,23 +17,31 @@ class SitePagesController < ApplicationController
end
def create
return normal_status(-1, "你还未开通Page服务无法进行部署") unless current_user.website_permission
return normal_status(-1, "你已使用了 #{params[:identifier]} 作为page标识") if Page.exists?(identifier: params[:identifier], user: current_user)
return normal_status(-1, "该仓库已开通Page服务") if Page.exists?(project: @project)
return normal_status(-1, '你还未开通Page服务无法进行部署') unless current_user.website_permission
return normal_status(-1, '你已开通Page服务') if Page.exists?(user: current_user)
return normal_status(-1, '该仓库已开通Page服务') if Page.exists?(project: @project)
@page = Page.new(create_params)
@page.user = current_user
@page.project = @project
@page.save
end
def update
return normal_status(-1, '你还未开通Page服务') unless current_user.website_permission
return normal_status(-1, '你还未开通Page站点') unless Page.exists?(user: current_user)
@page = Page.find_by(user: current_user)
@page.update(language_frame: params[:language_frame])
render_ok
end
def build
return normal_status(-1, "你还未开通Page服务无法进行部署") unless current_user.website_permission
return normal_status(-1, "该仓库还未开通Page服务无法进行部署") unless Page.exists?(project: @project)
return normal_status(-1, '你还未开通Page服务无法进行部署') unless current_user.website_permission
return normal_status(-1, '该仓库还未开通Page服务无法进行部署') unless Page.exists?(project: @project)
@page = Page.find params[:id]
return normal_status(-1, @page.state_description) unless @page.state
response_str = @page.deploy_page(params[:branch])
data = JSON.parse(response_str)["result"] || data = JSON.parse(response_str)["error"]
if data.to_s.include?("部署成功")
data = JSON.parse(response_str)['result'] || (data = JSON.parse(response_str)['error'])
if data.to_s.include?('部署成功')
@page.update(last_build_at: Time.now, build_state: true, last_build_info: data)
else
@page.update(build_state:false, last_build_info: data)
@ -42,22 +50,22 @@ class SitePagesController < ApplicationController
end
def softbot_build
branch = params[:ref].split("/").last
branch = params[:ref].split('/').last
user = User.find_by_login params[:repository][:owner][:login]
return normal_status(-1, "你还未开通Page服务无法进行部署") unless user.website_permission
return normal_status(-1, '你还未开通Page服务无法进行部署') unless user.website_permission
project = Project.where(identifier: params[:repository][:name],user_id: user.id)
return normal_status(-1, "你没有权限操作") if project.owner?(user)
return normal_status(-1, "该仓库还未开通Page服务无法进行部署") if Page.exists?(user: user, project: project)
return normal_status(-1, '你没有权限操作') if project.owner?(user)
return normal_status(-1, '该仓库还未开通Page服务无法进行部署') if Page.exists?(user: user, project: project)
@page = Page.find_by(user: user, project: project)
response_str = @page.deploy_page(branch)
data = JSON.parse(response_str)["result"]
data = JSON.parse(response_str)['result']
if data.nil?
data = JSON.parse(response_str)["error"]
data = JSON.parse(response_str)['error']
end
if data.include?("部署成功")
if data.include?('部署成功')
@page.update(last_build_at: Time.now, build_state: true, last_build_info: data)
else
@page.update(build_state:false, last_build_info: data)
@ -85,7 +93,7 @@ class SitePagesController < ApplicationController
end
def theme_params
params[:language_frame] || "hugo"
params[:language_frame] || 'hugo'
end
def create_params

View File

@ -0,0 +1,33 @@
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}", '')
next unless Project.find_by_id(project_id).present?
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

@ -1,44 +1,45 @@
# == Schema Information
#
# Table name: attachments
#
# id :integer not null, primary key
# container_id :integer
# container_type :string(30)
# filename :string(255) default(""), not null
# disk_filename :string(255) default(""), not null
# filesize :integer default("0"), not null
# content_type :string(255) default("")
# digest :string(60) default(""), not null
# downloads :integer default("0"), not null
# author_id :integer default("0"), not null
# created_on :datetime
# description :text(65535)
# disk_directory :string(255)
# attachtype :integer default("1")
# is_public :integer default("1")
# copy_from :integer
# quotes :integer default("0")
# is_publish :integer default("1")
# publish_time :datetime
# resource_bank_id :integer
# unified_setting :boolean default("1")
# cloud_url :string(255) default("")
# course_second_category_id :integer default("0")
# delay_publish :boolean default("0")
# memo_image :boolean default("0")
# extra_type :integer default("0")
# uuid :string(255)
#
# Indexes
#
# index_attachments_on_author_id (author_id)
# index_attachments_on_container_id_and_container_type (container_id,container_type)
# index_attachments_on_course_second_category_id (course_second_category_id)
# index_attachments_on_created_on (created_on)
# index_attachments_on_is_public (is_public)
# index_attachments_on_quotes (quotes)
#
# == Schema Information
#
# Table name: attachments
#
# id :integer not null, primary key
# container_id :integer
# container_type :string(30)
# filename :string(255) default(""), not null
# disk_filename :string(255) default(""), not null
# filesize :integer default("0"), not null
# content_type :string(255) default("")
# digest :string(60) default(""), not null
# downloads :integer default("0"), not null
# author_id :integer default("0"), not null
# created_on :datetime
# description :text(65535)
# disk_directory :string(255)
# attachtype :integer default("1")
# is_public :integer default("1")
# copy_from :integer
# quotes :integer default("0")
# is_publish :integer default("1")
# publish_time :datetime
# resource_bank_id :integer
# unified_setting :boolean default("1")
# cloud_url :string(255) default("")
# course_second_category_id :integer default("0")
# delay_publish :boolean default("0")
# memo_image :boolean default("0")
# extra_type :integer default("0")
# uuid :string(255)
#
# Indexes
#
# index_attachments_on_author_id (author_id)
# index_attachments_on_container_id_and_container_type (container_id,container_type)
# index_attachments_on_course_second_category_id (course_second_category_id)
# index_attachments_on_created_on (created_on)
# index_attachments_on_is_public (is_public)
# index_attachments_on_quotes (quotes)
#

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

@ -36,12 +36,17 @@
# blockchain_token_num :integer
# pm_project_id :integer
# pm_sprint_id :integer
# pm_issue_type :integer
# time_scale :decimal(10, 2) default("0.00")
# child_count :integer default("0")
# changer_id :integer
#
# Indexes
#
# index_issues_on_assigned_to_id (assigned_to_id)
# index_issues_on_author_id (author_id)
# index_issues_on_category_id (category_id)
# index_issues_on_changer_id (changer_id)
# index_issues_on_created_on (created_on)
# index_issues_on_fixed_version_id (fixed_version_id)
# index_issues_on_priority_id (priority_id)

View File

@ -14,6 +14,7 @@
# gid :integer
# gitea_url :string(255)
# pull_requests_count :integer default("0")
# pm_project_id :integer
#
# Indexes
#

View File

@ -27,6 +27,7 @@
#
# index_journals_on_created_on (created_on)
# index_journals_on_journalized_id (journalized_id)
# index_journals_on_parent_id (parent_id)
# index_journals_on_review_id (review_id)
# index_journals_on_user_id (user_id)
# journals_journalized_id (journalized_id,journalized_type)

View File

@ -34,6 +34,10 @@ class Page < ApplicationRecord
PageService.genernate_user(user_id)
end
before_destroy do
PageService.close_site(user_id, identifier)
end
before_save do
if state_changed? && state == false
PageService.close_site(user_id, identifier)
@ -46,7 +50,7 @@ class Page < ApplicationRecord
def url
@deploy_domain = EduSetting.find_by_name("site_page_deploy_domain").try(:value)
"http://#{user.login}.#{@deploy_domain}/#{identifier}"
"http://#{identifier}"
end
def build_script_path

View File

@ -136,6 +136,7 @@ class Project < ApplicationRecord
has_many :project_topic_ralates, dependent: :destroy
has_many :project_topics, through: :project_topic_ralates
has_many :commit_logs, dependent: :destroy
has_many :daily_project_statistics, dependent: :destroy
after_create :incre_user_statistic, :incre_platform_statistic
after_save :check_project_members
before_save :set_invite_code, :reset_unmember_followed, :set_recommend_and_is_pinned, :reset_cache_data

View File

@ -189,7 +189,7 @@ class User < Owner
has_many :user_clas, :dependent => :destroy
has_many :clas, through: :user_clas
has_many :pages, :dependent => :destroy
has_one :page, :dependent => :destroy
# Groups and active users
scope :active, lambda { where(status: [STATUS_ACTIVE, STATUS_EDIT_INFO]) }
@ -773,7 +773,7 @@ class User < Owner
def check_website_permission
if website_permission_changed? && website_permission == false
self.pages.update_all(state: false, state_description:"因违规使用现关闭Page服务")
self.page.update(state: false, state_description:"因违规使用现关闭Page服务")
PageService.close_site(self.id)
end
end

View File

@ -60,13 +60,31 @@ class Api::V1::Issues::ListService < ApplicationService
issues = issues.where(author_id: author_id) if author_id.present?
# issue_tag_ids
issues = issues.ransack(issue_tags_value_cont: issue_tag_ids.sort!.join(',')).result unless issue_tag_ids.blank?
if issue_tag_ids.present?
if issue_tag_ids.include?('-1')
issues = issues.where(issue_tags_value: nil).or(issues.where(issue_tags_value: ""))
else
issues = issues.ransack(issue_tags_value_cont: issue_tag_ids.sort!.join(',')).result
end
end
# milestone_id
issues = issues.where(fixed_version_id: milestone_id) if milestone_id.present?
if milestone_id.present?
if milestone_id.to_i == -1
issues = issues.where(fixed_version_id: nil)
else
issues = issues.where(fixed_version_id: milestone_id)
end
end
# assigner_id
issues = issues.joins(:assigners).where(users: {id: assigner_id}) if assigner_id.present?
if assigner_id.present?
if assigner_id.to_i == -1
issues = issues.left_joins(:assigners).where(users: {id: nil})
else
issues = issues.joins(:assigners).where(users: {id: assigner_id})
end
end
# status_id
issues = issues.where(status_id: status_id) if status_id.present? && category != 'closed'

View File

@ -26,7 +26,7 @@ class PageService
Rails.logger.info "################### PageService close_site #{user_id} / #{identifier}"
user = User.find user_id
uri = if identifier.present?
URI.parse("http://gitlink.#{@deploy_domain}/gitlink_execute_script?key=#{@deploy_key}&script_path=remove_dir&owner=#{user.login.downcase}/#{identifier}/")
URI.parse("http://gitlink.#{@deploy_domain}/gitlink_execute_script?key=#{@deploy_key}&script_path=remove_dir&owner=#{user.login.downcase}/*")
else
URI.parse("http://gitlink.#{@deploy_domain}/gitlink_execute_script?key=#{@deploy_key}&script_path=remove_dir&owner=#{user.login.downcase}/")
end

View File

@ -1,6 +1,6 @@
<%
define_admin_breadcrumbs do
add_admin_breadcrumb('云上实验室', admins_laboratories_path)
add_admin_breadcrumb('导航栏配置', admins_laboratories_path)
add_admin_breadcrumb('轮播图')
end
%>

View File

@ -1,5 +1,5 @@
<% define_admin_breadcrumbs do %>
<% add_admin_breadcrumb('云上实验室') %>
<% add_admin_breadcrumb('导航栏配置') %>
<% end %>
<div class="box search-form-container laboratory-list-form">

View File

@ -2,7 +2,7 @@
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">新建云上实验室</h5>
<h5 class="modal-title">新建导航栏配置</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>

View File

@ -1,5 +1,5 @@
<% define_admin_breadcrumbs do %>
<% add_admin_breadcrumb('云上实验室', admins_laboratories_path) %>
<% add_admin_breadcrumb('导航栏配置', admins_laboratories_path) %>
<% add_admin_breadcrumb('单位定制') %>
<% end %>

View File

@ -5,70 +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(:date, options_for_select(dates_array, params[:date]), class:"form-control",id: "project-rank-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 - 7.days).to_s%>" aria-label="选择日期">
</div>
<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-language-list-container">
<table class="table table-hover text-center subject-list-table">
<thead class="thead-light">
<tr>
<th width="20%">排名</th>
<th width="30%">项目</th>
<th width="10%">得分</th>
<th width="10%">访问数</th>
<th width="10%">关注数</th>
<th width="10%">点赞数</th>
<th width="10%">fork数</th>
<th width="10%">疑修数</th>
<th width="10%">合并请求数</th>
<th width="10%">提交数</th>
</tr>
</thead>
<tbody>
<% @date_rank.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>
</td>
<td><%= item[1] %></td>
<% 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") %>
<td><%= visits || 0 %></td>
<% watchers = $redis_cache.hget(project_date_statistic_key, "watchers") %>
<td><%= watchers || 0 %></td>
<% praises = $redis_cache.hget(project_date_statistic_key, "praises") %>
<td><%= praises || 0 %></td>
<% forks = $redis_cache.hget(project_date_statistic_key, "forks") %>
<td><%= forks || 0 %></td>
<% issues = $redis_cache.hget(project_date_statistic_key, "issues") %>
<td><%= issues || 0 %></td>
<% pullrequests = $redis_cache.hget(project_date_statistic_key, "pullrequests") %>
<td><%= pullrequests || 0 %></td>
<% commits = $redis_cache.hget(project_date_statistic_key, "commits") %>
<td><%= commits || 0 %></td>
<% else %>
<td colspan="7">暂无数据</td>
<% end %>
</tr>
<% end %>
</tbody>
</table>
<div class="box admin-list-container project-rank-list-container">
<%= render partial: 'admins/projects_rank/shared/data_list', locals: { statistics: @statistics } %>
</div>
<script>
$("#project-rank-date-select").on('change', function() {
$(".datetimepicker").on('change', function() {
$("#project-rank-date-form").submit()
});
$(".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

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

View File

@ -0,0 +1,37 @@
<table class="table table-hover text-center subject-list-table">
<thead class="thead-light">
<tr>
<th width="20%">排名</th>
<th width="30%">项目</th>
<th width="10%">得分</th>
<th width="10%"><%= sort_tag('访问数', name: 'visits', path: admins_projects_rank_index_path) %></th>
<th width="10%"><%= sort_tag('关注数', name: 'watchers', path: admins_projects_rank_index_path) %></th>
<th width="10%"><%= sort_tag('点赞数', name: 'praises', path: admins_projects_rank_index_path) %></th>
<th width="10%"><%= sort_tag('fork数', name: 'forks', path: admins_projects_rank_index_path) %></th>
<th width="10%"><%= sort_tag('疑修数', name: 'issues', path: admins_projects_rank_index_path) %></th>
<th width="10%"><%= sort_tag('合并请求数', name: 'pullrequests', path: admins_projects_rank_index_path) %></th>
<th width="10%"><%= sort_tag('提交数', name: 'commits', path: admins_projects_rank_index_path) %></th>
</tr>
</thead>
<tbody>
<% statistics.each_with_index do |item, index| %>
<tr class="">
<td><%= index + 1%></td>
<td>
<a target="_blank" href="<%= "/#{item&.project&.owner&.login}/#{item&.project&.identifier}"%>">
<%= "#{item&.project&.owner&.real_name}/#{item&.project&.name}" %>
</a>
</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>
</table>

View File

@ -11,13 +11,13 @@
<div class="modal-body">
<div class="form-group">
<label>
系统保留关键词标识 <span class="ml10 color-orange mr20">*</span>
禁用词标识 <span class="ml10 color-orange mr20">*</span>
</label>
<%= p.text_field :identifier,class: "form-control input-lg",required: true%>
</div>
<div class="form-group">
<label>
系统保留关键词描述
禁用词描述
</label>
<%= p.text_area :description,class: "form-control",placeholder: ""%>
</div>

View File

@ -1,5 +1,5 @@
<% define_admin_breadcrumbs do %>
<% add_admin_breadcrumb('系统保留关键词') %>
<% add_admin_breadcrumb('禁用词管理') %>
<% end %>
<div class="box search-form-container project-list-form">

View File

@ -13,13 +13,7 @@
<!-- Sidebar Links -->
<ul class="list-unstyled components">
<li><%= sidebar_item(admins_path, '概览', icon: 'dashboard', controller: 'admins-dashboards') %></li>
<li>
<%= sidebar_item_group('#rank-submenu', '排行榜', icon: 'calendar') do %>
<li><%= sidebar_item(admins_users_rank_index_path, '用户排行榜', icon: 'user', controller: 'admins-users_rank') %></li>
<li><%= sidebar_item(admins_projects_rank_index_path, '项目排行榜', icon: 'database', controller: 'admins-projects_rank') %></li>
<% end %>
</li>
<li><%= sidebar_item(admins_path, '数据概览', icon: 'dashboard', controller: 'admins-dashboards') %></li>
<li>
<%= sidebar_item_group('#user-submenu', '用户', icon: 'user') do %>
<li><%= sidebar_item(admins_users_path, '用户列表', icon: 'user', controller: 'admins-users') %></li>
@ -27,15 +21,23 @@
<% end %>
</li>
<li>
<%= sidebar_item_group('#pages-submenu', '站点管理', icon: 'cogs') do %>
<li><%= sidebar_item(admins_identity_verifications_path, '身份审核列表', icon: 'user', controller: 'admins-identity_verifications') %></li>
<li><%= sidebar_item(admins_site_pages_path, '用户站点列表', icon: 'sitemap', controller: 'admins-site_pages') %></li>
<li><%= sidebar_item(admins_page_themes_path, '站点主题配置', icon: 'cogs', controller: 'admins-page_themes') %></li>
<%= sidebar_item_group('#setting-submenu', '用户支持', icon: 'cogs') do %>
<li><%= sidebar_item(admins_faqs_path, 'FAQ', icon: 'question-circle', controller: 'admins-faqs') %></li>
<li><%= sidebar_item(admins_nps_path, 'NPS用户调研', icon: 'question-circle', controller: 'admins-nps') %></li>
<li><%= sidebar_item(admins_feedbacks_path, '用户反馈', icon: 'question-circle', controller: 'admins-feedbacks') %></li>
<li><%= sidebar_item(admins_system_notifications_path, '系统公告配置', icon: 'bell', controller: 'admins-system_notifications') %></li>
<% end %>
</li>
<li><%= sidebar_item(admins_laboratories_path, '导航栏配置', icon: 'cloud', controller: 'admins-laboratories') %></li>
<li>
<%= sidebar_item_group('#setting-system', '开发者配置', icon: 'wrench') do %>
<li><%= sidebar_item(admins_sites_path, 'setting接口配置', icon: 'deaf', controller: 'admins-sites') %></li>
<li><%= sidebar_item(admins_edu_settings_path, '全局变量配置', icon: 'pencil-square', controller: 'admins-edu_settings') %></li>
<li><%= sidebar_item(admins_message_templates_path, '消息模版配置', icon: 'folder', controller: 'admins-message_templates') %></li>
<% end %>
</li>
<li><%= sidebar_item(admins_reversed_keywords_path, '禁用词管理', icon: 'key', controller: 'admins-reversed_keywords') %></li>
<li>
<%= sidebar_item_group('#projects-submenu', '开源项目', icon: 'database') do %>
<li><%= sidebar_item(admins_projects_path, '项目列表', icon: 'database', controller: 'admins-projects') %></li>
@ -45,9 +47,6 @@
<li><%= sidebar_item(admins_project_ignores_path, '忽略文件', icon: 'git', controller: 'admins-project_ignores') %></li>
<% end %>
</li>
<li><%= sidebar_item(admins_reversed_keywords_path, '系统保留关键词', icon: 'key', controller: 'admins-reversed_keywords') %></li>
<li><%= sidebar_item(admins_laboratories_path, '云上实验室', icon: 'cloud', controller: 'admins-laboratories') %></li>
<li>
<%= sidebar_item_group('#setting-index', '首页配置', icon: 'file') do %>
<li><%= sidebar_item(admins_topic_banners_path, 'banner管理', icon: 'image', controller: 'admins-topic-banners') %></li>
@ -71,25 +70,26 @@
<% end %>
</li>
<li>
<%= sidebar_item_group('#setting-submenu', '网站建设', icon: 'cogs') do %>
<li><%= sidebar_item(admins_faqs_path, 'FAQ', icon: 'question-circle', controller: 'admins-faqs') %></li>
<li><%= sidebar_item(admins_nps_path, 'NPS用户调研', icon: 'question-circle', controller: 'admins-nps') %></li>
<li><%= sidebar_item(admins_feedbacks_path, '用户反馈', icon: 'question-circle', controller: 'admins-feedbacks') %></li>
<%= sidebar_item_group('#pages-submenu', '个人站点管理', icon: 'cogs') do %>
<li><%= sidebar_item(admins_identity_verifications_path, '身份审核列表', icon: 'user', controller: 'admins-identity_verifications') %></li>
<li><%= sidebar_item(admins_site_pages_path, '用户站点列表', icon: 'sitemap', controller: 'admins-site_pages') %></li>
<li><%= sidebar_item(admins_page_themes_path, '站点主题配置', icon: 'cogs', controller: 'admins-page_themes') %></li>
<% end %>
</li>
<li>
<%= sidebar_item_group('#setting-system', '系统配置', icon: 'wrench') do %>
<li><%= sidebar_item(admins_sites_path, 'setting接口配置', icon: 'deaf', controller: 'admins-sites') %></li>
<li><%= sidebar_item(admins_edu_settings_path, '全局变量配置', icon: 'pencil-square', controller: 'admins-edu_settings') %></li>
<li><%= sidebar_item(admins_system_notifications_path, '系统通知配置', icon: 'bell', controller: 'admins-system_notifications') %></li>
<li><%= sidebar_item(admins_message_templates_path, '消息模版配置', icon: 'folder', controller: 'admins-message_templates') %></li>
<%= sidebar_item_group('#rank-submenu', '活跃度排行', icon: 'calendar') do %>
<li><%= sidebar_item(admins_users_rank_index_path, '用户活跃度排行', icon: 'user', controller: 'admins-users_rank') %></li>
<li><%= sidebar_item(admins_projects_rank_index_path, '项目活跃度排行', icon: 'database', controller: 'admins-projects_rank') %></li>
<% end %>
</li>
<%= render_admin_statistics_item %>
<li>
<%= sidebar_item('/admins/sidekiq', '定时任务', icon: 'bell', controller: 'root') %>
</li>
<%= render_admin_statistics_item %>
<li><%= sidebar_item('/', '返回主站', icon: 'sign-out', controller: 'root') %></li>
</ul>

View File

@ -1,5 +1,5 @@
<div class="box search-form-container project-list-form">
<div style="line-height: 38px;" class="flex-1"><%= type == "create" ? "新建" : "编辑" %>系统通知</div>
<div style="line-height: 38px;" class="flex-1"><%= type == "create" ? "新建" : "编辑" %>系统公告</div>
<%= link_to "返回", admins_system_notifications_path, class: "btn btn-default pull-right" %>
</div>
@ -8,36 +8,36 @@
<div class="form-group">
<label>
<span class="color-grey-6 pt10">
系统通知标题
系统公告标题
<span class="ml10 color-orange mr20">*</span>
</span>
</label>
<div class="mt-10">
<%= p.text_field :subject, class: "form-control input-lg", placeholder: "请输入系统通知标题" %>
<%= p.text_field :subject, class: "form-control input-lg", placeholder: "请输入系统公告标题" %>
</div>
</div>
<div class="form-group">
<label>
<span class="color-grey-6 pt10">
系统通知副标题
系统公告副标题
<span class="ml10 color-orange mr20">*</span>
</span>
</label>
<div class="mt-10">
<%= p.text_field :sub_subject, class: "form-control input-lg", placeholder: "请输入系统通知副标题" %>
<%= p.text_field :sub_subject, class: "form-control input-lg", placeholder: "请输入系统公告副标题" %>
</div>
</div>
<div class="form-group">
<label>
<span class="color-grey-6 pt10">
系统通知正文
系统公告正文
<span class="ml10 color-orange mr20">*</span>
</span>
</label>
<div class="pl-0 my-3 setting-item-body" id="system-notification-content-editor">
<%= p.text_area :content, class:"form-control", style: 'display: none;', rows: "10", cols: "20", placeholer: "请输入系统通知正文" %>
<%= p.text_area :content, class:"form-control", style: 'display: none;', rows: "10", cols: "20", placeholer: "请输入系统公告正文" %>
</div>
</div>

View File

@ -1,11 +1,11 @@
<% define_admin_breadcrumbs do %>
<% add_admin_breadcrumb('系统通知模版') %>
<% add_admin_breadcrumb('系统公告配置') %>
<% end %>
<div id="admins-system-notification-content">
<div class="box search-form-container project-list-form">
<%= form_tag(admins_system_notifications_path, method: :get, class: 'form-inline search-form flex-1', remote: true) do %>
<%= text_field_tag(:search, params[:search], class: 'form-control col-12 col-md-2 mr-3', placeholder: '系统通知标题检索') %>
<%= text_field_tag(:search, params[:search], class: 'form-control col-12 col-md-2 mr-3', placeholder: '系统公告标题检索') %>
<%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %>
<input type="reset" class="btn btn-secondary clear-btn" value="清空"/>
<% end %>

View File

@ -34,7 +34,7 @@
<td><%= index + 1%></td>
<% owner_common = $redis_cache.hgetall("v2-owner-common:#{item[0]}")%>
<td>
<a href="/<%= owner_common["login"] %>">
<a target="_blank" href="/<%= owner_common["login"] %>">
<%= owner_common["name"] %>
</a>
</td>

View File

@ -19,6 +19,7 @@ json.version_releasesed_count @project.releases_size(@user.try(:id), "released")
json.permission render_permission(@user, @project)
json.mirror_url @project&.repository.remote_mirror_url
json.mirror @project&.repository.mirror_url.present?
json.web_site @project.page.try(:identifier)
json.type @project.numerical_for_project_type
json.open_devops @project.open_devops?
json.topics @project.project_topics.each do |topic|

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

View File

@ -68,7 +68,8 @@ namespace :batch_add_issues do
UserExtension.create!(user_id: user.id)
puts "import_user batch success: phone #{phone} email: #{email}"
end
title = issue['title']
title = title[0..190] if title.size > 190
issue_params = {
:status_id => issue_status,
:priority_id => priority,
@ -76,7 +77,7 @@ namespace :batch_add_issues do
# :branch_name,
# :start_date,
# :due_date,
:subject => issue['title'],
:subject => title,
:description => issue['body'],
# :blockchain_token_num,
:issue_tag_ids => [],
@ -127,4 +128,152 @@ namespace :batch_add_issues do
end
end
end
task github: :environment do
project_id = ENV['project_id']
puts "project_id=================#{project_id}"
next if project_id.blank?
project = Project.find project_id
count = 0
if ENV['count'].present?
count = ENV['count'].to_i
end
total_count = 3000
puts "total_count==========#{total_count}"
if total_count > 100
total_page = (total_count / 100) + 1
total_page.times do |i|
sleep 1.seconds
add_github_issues_to_project(project, i + 1 + count)
end
else
add_github_issues_to_project(project, 1)
end
end
def add_github_issues_to_project(project,page)
# curl -X GET --header 'Content-Type: application/json;charset=UTF-8' 'https://gitee.com/api/v5/repos/mindspore/mindspore/issues?access_token=5ccebd935915fb6cfcae634b161047a2&state=open&sort=created&direction=desc&page=1&per_page=10'
# api_url = "https://gitee.com/api/v5/repos/mindspore/mindspore/issues?access_token=96a637aa055f15056e77e3cf11a67525&state=all&sort=created&direction=desc&page=#{page}&per_page=100"
api_url = "https://api.github.com/repos/OpenXiangShan/XiangShan/issues?sort=created&direction=desc&per_page=100&state=all&page=#{page}"
uri = URI.parse(api_url)
# response = Net::HTTP.get_response(uri)
http = Net::HTTP.new(uri.hostname, uri.port)
http.use_ssl = true
response = http.send_request('GET', uri, nil, {'Content-Type' => 'application/json','authorization' => "Bearer #{ENV['token']}"})
puts "gitee api response.code ===== #{response.code}"
lists = JSON.parse(response.body)
puts "lists.size =====#{lists.size}"
# "1" => "新增",
# "2" => "正在解决",
# "3" => "已解决",
# "5" => "关闭",
# "6" => "拒绝"
# Issue的状态: open开启的, progressing(进行中), closed关闭的, rejected拒绝的。 默认: open
lists.each do |issue|
next if issue['pull_request'].present?
title = issue['title']
title = title[0..190] if title.size > 190
created_issue = Issue.find_by(project_id: project.id, subject: title)
issue_created_at = issue['created_at']
issue_updated_at = issue['updated_at']
unless created_issue.present?
priority = [1, 2, 3, 4].include?(issue['priority'].to_i) ? issue['priority'].to_i : 2
issue_status = ["", "open", "progressing", "", "", "closed", "rejected"].index(issue['state'])
issue_status = 1 if issue_status.nil?
user_login = issue['user']['login']
user_login = user_login[0..20] if user_login.size > 29
username = "gh-#{user_login}"
user = User.find_by(login: username)
unless user.present?
email = "#{username}@gitlink.org.cn"
phone = ""
password = "a12345678"
user = User.new(nickname: username, login: username, mail: email, password: password, type: 'User', phone: phone)
interactor = Gitea::RegisterInteractor.call({ username: username, email: email, password: password })
gitea_user = interactor.result
result = Gitea::User::GenerateTokenService.call(username, password)
user.gitea_token = result['sha1']
user.gitea_uid = gitea_user[:body]['id']
user.created_on = issue_created_at
user.updated_on = issue_created_at
user.is_test = true
user.save!
UserExtension.create!(user_id: user.id)
puts "import_user batch success: phone #{phone} email: #{email}"
end
issue_tags_value = []
if issue['labels'].present?
issue['labels'].each do |tag|
label = project.issue_tags.find_or_create_by!(name: tag['name'], description: tag['description'], color: "##{tag['color']}")
issue_tags_value.push(label.id)
end
end
issue_params = {
:status_id => issue_status,
:priority_id => priority,
# :milestone_id,
# :branch_name,
# :start_date,
# :due_date,
:subject => title,
:description => issue['body'],
# :blockchain_token_num,
:issue_tag_ids => issue_tags_value,
:assigner_ids => [],
:attachment_ids => [],
:receivers_login => []
}
created_issue = Api::V1::Issues::CreateService.call(project, issue_params, user)
end
issue_number = issue['number']
sleep 1.seconds
# comment_api_url = "https://gitee.com/api/v5/repos/mindspore/mindspore/issues/#{issue_number}/comments?access_token=96a637aa055f15056e77e3cf11a67525&page=1&per_page=100&order=asc"
comment_api_url = "https://api.github.com/repos/OpenXiangShan/XiangShan/issues/#{issue_number}/comments?page=1&per_page=100"
comment_uri = URI.parse(comment_api_url)
# comment_response = Net::HTTP.get_response(comment_uri)
http = Net::HTTP.new(comment_uri.hostname, comment_uri.port)
http.use_ssl = true
comment_response = http.send_request('GET', comment_uri, nil, {'Content-Type' => 'application/json','authorization' => "Bearer #{ENV['token']}"})
comment_lists = JSON.parse(comment_response.body)
comment_lists.each do |comment|
next if Journal.find_by(journalized_id: created_issue.id, journalized_type: 'Issue', notes: comment['body']).present?
user_login = comment['user']['login']
next if user_login.size >29
comment_created_at = comment['created_at']
comment_updated_at = comment['updated_at']
username = "gh-#{user_login}"
comment_user = User.find_by(login: username)
unless comment_user.present?
email = "#{username}@gitlink.org.cn"
phone = ""
password = "a12345678"
comment_user = User.new(nickname: username, login: username, mail: email, password: password, type: 'User', phone: phone)
interactor = Gitea::RegisterInteractor.call({ username: username, email: email, password: password })
gitea_user = interactor.result
result = Gitea::User::GenerateTokenService.call(username, password)
comment_user.gitea_token = result['sha1']
comment_user.gitea_uid = gitea_user[:body]['id']
comment_user.created_on = comment_created_at
comment_user.updated_on = comment_created_at
comment_user.save!
UserExtension.create!(user_id: comment_user.id)
end
journal_params = {:notes => comment['body'],
:attachment_ids => [],
:receivers_login => []}
object_result = Api::V1::Issues::Journals::CreateService.call(created_issue, journal_params, comment_user)
object_result.update_columns(created_on: comment_created_at, updated_on: comment_updated_at)
created_issue.update_columns(created_on: issue_created_at, updated_on: issue_updated_at)
end
end
end
end