diff --git a/.gitignore b/.gitignore
index 5935e048d..6af1a6cd4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,6 +11,7 @@
# Ignore lock config file
*.log
.rubocop.yml
+.env
# mac
*.DS_Store
.bashrc
@@ -84,4 +85,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/Gemfile b/Gemfile
index 8fd3e7cff..edaae8a75 100644
--- a/Gemfile
+++ b/Gemfile
@@ -141,4 +141,4 @@ gem 'doorkeeper'
gem 'doorkeeper-jwt'
-gem 'gitea-client', '~> 1.4.3'
+gem 'gitea-client', '~> 1.4.6'
diff --git a/app/controllers/admins/dashboards_controller.rb b/app/controllers/admins/dashboards_controller.rb
index 2c01c8bd0..6940ed1cf 100644
--- a/app/controllers/admins/dashboards_controller.rb
+++ b/app/controllers/admins/dashboards_controller.rb
@@ -21,13 +21,75 @@ class Admins::DashboardsController < Admins::BaseController
weekly_project_ids = (CommitLog.where(created_at: current_week).pluck(:project_id).uniq + Issue.where(created_on: current_week).pluck(:project_id).uniq).uniq
month_project_ids = (CommitLog.where(created_at: current_month).pluck(:project_id).uniq + Issue.where(created_on: current_month).pluck(:project_id).uniq).uniq
@day_active_project_count = Project.where(updated_on: today).or(Project.where(id: day_project_ids)).count
- @weekly_active_project_count = Project.where(updated_on: current_week).or(Project.where(id: weekly_project_ids)).count
- @month_active_project_count = Project.where(updated_on: current_month).or(Project.where(id: month_project_ids)).count
-
+ @weekly_active_project_count = Rails.cache.fetch("dashboardscontroller:weekly_active_project_count", expires_in: 10.minutes) do
+ Project.where(updated_on: current_week).or(Project.where(id: weekly_project_ids)).count
+ end
+ @month_active_project_count = Rails.cache.fetch("dashboardscontroller:month_active_project_count", expires_in: 1.hours) do
+ Project.where(updated_on: current_month).or(Project.where(id: month_project_ids)).count
+ end
# 新增项目数
- @day_new_project_count = Project.where(created_on: today).count
- @weekly_new_project_count = Project.where(created_on: current_week).count
- @month_new_project_count = Project.where(created_on: current_month).count
+ @day_new_project_count = Rails.cache.fetch("dashboardscontroller:day_new_project_count", expires_in: 10.minutes) do
+ Project.where(created_on: today).count
+ end
+ @weekly_new_project_count = Rails.cache.fetch("dashboardscontroller:weekly_new_project_count", expires_in: 10.minutes) do
+ Project.where(created_on: current_week).count
+ end
+ @month_new_project_count = Rails.cache.fetch("dashboardscontroller:month_new_project_count", expires_in: 1.hours) do
+ Project.where(created_on: current_month).count
+ end
+
+
+ # 总的平台用户数
+ # 总的平台项目数
+ # 总的平台组织数
+ # 总的平台Issue数、评论数、PR数、Commit数
+ @user_count = Rails.cache.fetch("dashboardscontroller:platform:user_count", expires_in: 1.days) do
+ User.count
+ end
+ @project_count = Rails.cache.fetch("dashboardscontroller:platform:project_count", expires_in: 1.days) do
+ Project.count
+ end
+ @organization_count = Rails.cache.fetch("dashboardscontroller:platform:organization_count", expires_in: 1.days) do
+ Organization.count
+ end
+ @issue_count = Rails.cache.fetch("dashboardscontroller:platform:issue_count", expires_in: 1.days) do
+ Issue.count
+ end
+ @comment_count = Rails.cache.fetch("dashboardscontroller:platform:comment_count", expires_in: 1.days) do
+ Journal.count
+ end
+ @pr_count = Rails.cache.fetch("dashboardscontroller:platform:pr_count", expires_in: 1.days) do
+ PullRequest.count
+ end
+ @commit_count = Rails.cache.fetch("dashboardscontroller:platform:commit_count", expires_in: 1.days) do
+ CommitLog.count
+ end
+
+ @subject_name = ["用户数", "项目数", "组织数", "Issue数", "Issue评论数", "PR数", "Commit数"]
+ @subject_icon = ["fa-user","fa-git", "fa-sitemap", "fa-warning", "fa-comments", "fa-share-alt", "fa-upload"]
+ @subject_data = [@user_count, @project_count, @organization_count, @issue_count, @comment_count, @pr_count, @commit_count]
+
+
+ tongji_service = Baidu::TongjiService.new
+ @access_token = tongji_service.access_token
+ Rails.logger.info "baidu_tongji_auth access_token ===== #{@access_token}"
+ # @overview_data = tongji_service.api_overview
+ last_date = DailyPlatformStatistic.order(:date).last
+ start_date = last_date.date
+ end_date = Time.now
+ if @access_token.present?
+ @overview_data = Rails.cache.fetch("dashboardscontroller:baidu_tongji:overview_data", expires_in: 10.minutes) do
+ tongji_service.source_from_batch_add(start_date, end_date)
+ @overview_data = tongji_service.overview_batch_add(start_date, end_date)
+ @overview_data
+ end
+ end
+
+ @current_week_statistic = DailyPlatformStatistic.where(date: current_week)
+ @pre_week_statistic = DailyPlatformStatistic.where(date: pre_week)
+
+
+
end
def month_active_user
@@ -42,6 +104,19 @@ class Admins::DashboardsController < Admins::BaseController
render_ok(data: data)
end
+ def baidu_tongji
+ tongji_service = Baidu::TongjiService.new
+ redirect_to tongji_service.code_url
+ end
+
+ def baidu_tongji_auth
+ if params[:code].present?
+ tongji_service = Baidu::TongjiService.new
+ tongji_service.get_access_token(params[:code])
+ end
+ redirect_to "/admins/"
+ end
+
def evaluate
names = []
data = []
@@ -63,8 +138,12 @@ class Admins::DashboardsController < Admins::BaseController
Time.now.beginning_of_day..Time.now.end_of_day
end
- def current_week
+ def pre_7_days
7.days.ago.end_of_day..Time.now.end_of_day
+ end
+
+ def current_week
+ Time.now.beginning_of_week..Time.now.end_of_day
end
def current_month
@@ -72,6 +151,7 @@ class Admins::DashboardsController < Admins::BaseController
end
def pre_week
- 14.days.ago.end_of_day..7.days.ago.end_of_day
+ # 14.days.ago.end_of_day..7.days.ago.end_of_day
+ Time.now.prev_week..Time.now.prev_week.end_of_week
end
end
\ No newline at end of file
diff --git a/app/controllers/admins/identity_verifications_controller.rb b/app/controllers/admins/identity_verifications_controller.rb
index 51d5e423c..1db1a9883 100644
--- a/app/controllers/admins/identity_verifications_controller.rb
+++ b/app/controllers/admins/identity_verifications_controller.rb
@@ -14,12 +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 c4f968da4..8db0961b7 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.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, "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
\ No newline at end of file
diff --git a/app/controllers/admins/site_pages_controller.rb b/app/controllers/admins/site_pages_controller.rb
index f0e05e71d..306c91627 100644
--- a/app/controllers/admins/site_pages_controller.rb
+++ b/app/controllers/admins/site_pages_controller.rb
@@ -29,8 +29,12 @@ class Admins::SitePagesController < Admins::BaseController
end
def update
- @site_page.update(update_params)
- flash[:success] = '保存成功'
+ if update_params[:state] == "false" && update_params[:state_description].blank?
+ flash[:danger] = '关闭站点理由不能为空'
+ else
+ @site_page.update(update_params)
+ flash[:success] = '保存成功'
+ end
render 'edit'
end
diff --git a/app/controllers/admins/system_notifications_controller.rb b/app/controllers/admins/system_notifications_controller.rb
index e2081f1a2..33f3f20f1 100644
--- a/app/controllers/admins/system_notifications_controller.rb
+++ b/app/controllers/admins/system_notifications_controller.rb
@@ -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
diff --git a/app/controllers/api/v1/projects/actions/actions_controller.rb b/app/controllers/api/v1/projects/actions/actions_controller.rb
new file mode 100644
index 000000000..3825b4685
--- /dev/null
+++ b/app/controllers/api/v1/projects/actions/actions_controller.rb
@@ -0,0 +1,31 @@
+class Api::V1::Projects::Actions::ActionsController < Api::V1::Projects::Actions::BaseController
+
+ def index
+ begin
+ gitea_result = $gitea_hat_client.get_repos_actions_by_owner_repo(@project&.owner&.login, @project&.identifier)
+ @data = gitea_result[:data]["Workflows"]
+ rescue
+ @data = []
+ end
+ end
+
+ def disable
+ return render_error("请输入正确的流水线文件!") if params[:workflow].blank?
+ gitea_result = $gitea_hat_client.post_repos_actions_disable(@project&.owner&.login, @project&.identifier, {query: {workflow: params[:workflow]}}) rescue nil
+ if gitea_result
+ render_ok
+ else
+ render_error("禁用流水线失败")
+ end
+ end
+
+ def enable
+ return render_error("请输入正确的流水线文件!") if params[:workflow].blank?
+ gitea_result = $gitea_hat_client.post_repos_actions_enable(@project&.owner&.login, @project&.identifier, {query: {workflow: params[:workflow]}}) rescue nil
+ if gitea_result
+ render_ok
+ else
+ render_error("取消禁用流水线失败")
+ end
+ end
+end
\ No newline at end of file
diff --git a/app/controllers/api/v1/projects/actions/base_controller.rb b/app/controllers/api/v1/projects/actions/base_controller.rb
new file mode 100644
index 000000000..d76b446ad
--- /dev/null
+++ b/app/controllers/api/v1/projects/actions/base_controller.rb
@@ -0,0 +1,4 @@
+class Api::V1::Projects::Actions::BaseController < Api::V1::BaseController
+ before_action :require_public_and_member_above
+
+end
\ No newline at end of file
diff --git a/app/controllers/api/v1/projects/actions/runs_controller.rb b/app/controllers/api/v1/projects/actions/runs_controller.rb
new file mode 100644
index 000000000..b9eb9ff06
--- /dev/null
+++ b/app/controllers/api/v1/projects/actions/runs_controller.rb
@@ -0,0 +1,12 @@
+class Api::V1::Projects::Actions::RunsController < Api::V1::Projects::Actions::BaseController
+
+ def index
+ @result_object = Api::V1::Projects::Actions::Runs::ListService.call(@project, {workflow: params[:workflow], page: page, limit: limit}, current_user&.gitea_token)
+ end
+
+ def job_show
+ @result_object = Api::V1::Projects::Actions::Runs::JobShowService.call(@project, params[:run_id], params[:job], params[:log_cursors], current_user&.gitea_token)
+ puts @result_object
+ end
+
+end
\ No newline at end of file
diff --git a/app/controllers/api/v1/projects/branches_controller.rb b/app/controllers/api/v1/projects/branches_controller.rb
index 40f44fea5..89ebb5825 100644
--- a/app/controllers/api/v1/projects/branches_controller.rb
+++ b/app/controllers/api/v1/projects/branches_controller.rb
@@ -2,14 +2,14 @@ class Api::V1::Projects::BranchesController < Api::V1::BaseController
before_action :require_public_and_member_above, only: [:index, :all]
def index
- @result_object = Api::V1::Projects::Branches::ListService.call(@project, {name: params[:keyword], page: page, limit: limit}, current_user&.gitea_token)
+ @result_object = Api::V1::Projects::Branches::ListService.call(@project, {name: params[:keyword], state: params[:state], page: page, limit: limit}, current_user&.gitea_token)
end
def all
@result_object = Api::V1::Projects::Branches::AllListService.call(@project, current_user&.gitea_token)
end
- before_action :require_operate_above, only: [:create, :destroy]
+ before_action :require_operate_above, only: [:create, :destroy, :restore]
def create
@result_object = Api::V1::Projects::Branches::CreateService.call(@project, branch_params, current_user&.gitea_token)
@@ -33,6 +33,15 @@ class Api::V1::Projects::BranchesController < Api::V1::BaseController
end
end
+ def restore
+ @result_object = Api::V1::Projects::Branches::RestoreService.call(@project, params[:branch_id], params[:branch_name], current_user&.gitea_token)
+ if @result_object
+ return render_ok
+ else
+ return render_error('恢复分支失败!')
+ end
+ end
+
before_action :require_manager_above, only: [:update_default_branch]
def update_default_branch
diff --git a/app/controllers/api/v1/projects/commits_controller.rb b/app/controllers/api/v1/projects/commits_controller.rb
index a1545ae6f..9fd8de1c2 100644
--- a/app/controllers/api/v1/projects/commits_controller.rb
+++ b/app/controllers/api/v1/projects/commits_controller.rb
@@ -1,5 +1,5 @@
class Api::V1::Projects::CommitsController < Api::V1::BaseController
- before_action :require_public_and_member_above, only: [:index, :diff]
+ before_action :require_public_and_member_above, only: [:index, :diff, :recent]
def index
@result_object = Api::V1::Projects::Commits::ListService.call(@project, {page: page, limit: limit, sha: params[:sha]}, current_user&.gitea_token)
@@ -9,4 +9,8 @@ class Api::V1::Projects::CommitsController < Api::V1::BaseController
def diff
@result_object = Api::V1::Projects::Commits::DiffService.call(@project, params[:sha], current_user&.gitea_token)
end
+
+ def recent
+ @result_object = Api::V1::Projects::Commits::RecentService.call(@project, {page: page, limit: limit}, current_user&.gitea_token)
+ end
end
\ No newline at end of file
diff --git a/app/controllers/organizations/organization_users_controller.rb b/app/controllers/organizations/organization_users_controller.rb
index d9035dc14..171e9dcae 100644
--- a/app/controllers/organizations/organization_users_controller.rb
+++ b/app/controllers/organizations/organization_users_controller.rb
@@ -4,17 +4,31 @@ class Organizations::OrganizationUsersController < Organizations::BaseController
before_action :check_user_can_edit_org, only: [:destroy]
def index
- @organization_users = @organization.organization_users.includes(:user)
+ # @organization_users = @organization.organization_users.includes(:user)
+ # if params[:search].present?
+ # search = params[:search].to_s.downcase
+ # user_condition_users = User.like(search).to_sql
+ # team_condition_teams = User.joins(:teams).merge(@organization.teams.like(search)).to_sql
+ # users = User.from("( #{user_condition_users} UNION #{team_condition_teams }) AS users")
+ #
+ # @organization_users = @organization_users.where(user_id: users).distinct
+ # end
+ #
+ # @organization_users = kaminari_paginate(@organization_users)
+
+ organization_user_ids = @organization.organization_users.pluck(:user_id).uniq
+ project_member_user_ids = @organization.projects.joins(:members).pluck("members.user_id").uniq
+ ids = organization_user_ids + project_member_user_ids
+ users = User.where(id: ids).reorder(Arel.sql("FIELD(users.id,#{ids.join(',')})"))
if params[:search].present?
search = params[:search].to_s.downcase
user_condition_users = User.like(search).to_sql
team_condition_teams = User.joins(:teams).merge(@organization.teams.like(search)).to_sql
- users = User.from("( #{user_condition_users} UNION #{team_condition_teams }) AS users")
+ user_ids = User.from("( #{user_condition_users} UNION #{team_condition_teams }) AS users").pluck(:id)
- @organization_users = @organization_users.where(user_id: users).distinct
+ users = users.where(id: user_ids)
end
-
- @organization_users = kaminari_paginate(@organization_users)
+ @users = kaminari_paginate(users)
end
def pm_check_user
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index fbc65960a..c0230f5f8 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -338,7 +338,7 @@ class ProjectsController < ApplicationController
def project_params
params.permit(:user_id, :name, :description, :repository_name, :website, :lesson_url, :default_branch, :identifier,
- :project_category_id, :project_language_id, :license_id, :ignore_id, :private,
+ :project_category_id, :project_language_id, :license_id, :ignore_id, :private, :auto_init,
:blockchain, :blockchain_token_all, :blockchain_init_token, :pr_view_admin)
end
diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb
index e26559f74..c8e4380e0 100644
--- a/app/controllers/repositories_controller.rb
+++ b/app/controllers/repositories_controller.rb
@@ -66,6 +66,8 @@ class RepositoriesController < ApplicationController
@entries = Gitea::Repository::Entries::ListService.new(@owner, @project.identifier, ref: @ref).call
@entries = @entries.present? ? @entries.sort_by{ |hash| hash['type'] } : []
@path = GiteaService.gitea_config[:domain]+"/#{@project.owner.login}/#{@project.identifier}/raw/branch/#{@ref}/"
+ @repo_detail = $gitea_client.get_repos_by_owner_repo(@owner.login, @project.identifier)
+ return render_not_found if @entries.blank? && !@repo_detail["empty"]
end
end
diff --git a/app/controllers/site_pages_controller.rb b/app/controllers/site_pages_controller.rb
index 903e037db..085f1b027 100644
--- a/app/controllers/site_pages_controller.rb
+++ b/app/controllers/site_pages_controller.rb
@@ -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
diff --git a/app/forms/organizations/create_form.rb b/app/forms/organizations/create_form.rb
index 2163f477e..1f40350b3 100644
--- a/app/forms/organizations/create_form.rb
+++ b/app/forms/organizations/create_form.rb
@@ -1,12 +1,12 @@
class Organizations::CreateForm < BaseForm
- NAME_REGEX = /^(?!_)(?!.*?_$)[a-zA-Z0-9_-]+$/ #只含有数字、字母、下划线不能以下划线开头和结尾
+ NAME_REGEX = /^[a-zA-Z0-9]+([-_.][a-zA-Z0-9]+)*$/ #只含有数字、字母、下划线不能以下划线开头和结尾
attr_accessor :name, :description, :website, :location, :repo_admin_change_team_access, :visibility, :max_repo_creation, :nickname, :original_name
validates :name, :nickname, :visibility, presence: true
validates :name, :nickname, length: { maximum: 100 }
validates :location, length: { maximum: 50 }
validates :description, length: { maximum: 200 }
- validates :name, format: { with: NAME_REGEX, multiline: true, message: "只能含有数字、字母、下划线且不能以下划线开头和结尾" }
+ validates :name, format: { with: NAME_REGEX, multiline: true, message: "只能以数字或字母开头,仅支持横杠、下划线、点三种符号,不允许符号连续排列,长度4-50个字符" }
validate do
check_name(name) unless name.blank? || name == original_name
diff --git a/app/forms/projects/create_form.rb b/app/forms/projects/create_form.rb
index c133175c2..fd0128c3d 100644
--- a/app/forms/projects/create_form.rb
+++ b/app/forms/projects/create_form.rb
@@ -1,6 +1,6 @@
class Projects::CreateForm < BaseForm
attr_accessor :user_id, :name, :description, :repository_name, :project_category_id,
- :project_language_id, :ignore_id, :license_id, :private, :owner,
+ :project_language_id, :ignore_id, :license_id, :private, :owner, :auto_init,
:blockchain, :blockchain_token_all, :blockchain_init_token
validates :user_id, :name, :repository_name, presence: true
@@ -10,7 +10,7 @@ class Projects::CreateForm < BaseForm
validates :repository_name, length: { maximum: 100 }
validates :description, length: { maximum: 200 }
- validate :check_ignore, :check_license, :check_owner, :check_max_repo_creation
+ validate :check_ignore, :check_license, :check_auto_init, :check_owner, :check_max_repo_creation
validate do
check_project_category(project_category_id)
check_project_language(project_language_id)
@@ -28,6 +28,10 @@ class Projects::CreateForm < BaseForm
raise "ignore_id值无效." if ignore_id && Ignore.find_by(id: ignore_id).blank?
end
+ def check_auto_init
+ raise "auto_init值无效." if ignore_id && license_id && !auto_init
+ end
+
def check_owner
@project_owner = Owner.find_by(id: user_id)
raise "user_id值无效." if user_id && @project_owner.blank?
diff --git a/app/interactors/gitea/delete_file_interactor.rb b/app/interactors/gitea/delete_file_interactor.rb
index 03ddf4230..f94b8a205 100644
--- a/app/interactors/gitea/delete_file_interactor.rb
+++ b/app/interactors/gitea/delete_file_interactor.rb
@@ -45,6 +45,7 @@ module Gitea
else
Rails.logger.error("Gitea::Repository::Entries::DeleteService error[#{response.status}]======#{response.body}")
@error = "删除失败,请确认该分支是否是保护分支。"
+ @error = "删除失败,参数sha不匹配。" if response.body.to_s.include?("sha does not match")
end
end
diff --git a/app/jobs/daily_platform_statistics_job.rb b/app/jobs/daily_platform_statistics_job.rb
new file mode 100644
index 000000000..5610f304b
--- /dev/null
+++ b/app/jobs/daily_platform_statistics_job.rb
@@ -0,0 +1,44 @@
+# 按天获取百度统计数据,pv,访问,ip和来源分类占比
+# 其他统计:前一周用户留存率
+class DailyPlatformStatisticsJob < ApplicationJob
+ queue_as :default
+
+ def perform(*args)
+ Rails.logger.info("*********开始统计*********")
+
+ tongji_service = Baidu::TongjiService.new
+ access_token = tongji_service.access_token
+ Rails.logger.info "job baidu_tongji_auth access_token ===== #{access_token}"
+ ActiveJob::Base.logger.info "job baidu_tongji_auth access_token ===== #{access_token}"
+ # 从最后一个记录日期开始,如果遗漏日期数据可以补充数据
+ last_date = DailyPlatformStatistic.order(:date).last
+ start_date = last_date.date
+ end_date = Time.now
+ if access_token.present?
+ tongji_service.overview_batch_add(start_date, end_date)
+
+ # 本周访问来源占比,每天记录一次,如果遗漏日期数据可以补充数据
+ tongji_service.source_from_batch_add(start_date, end_date)
+ end
+ # 周用户留存率
+ pre_week_user_ids = User.where(created_on: pre_week).pluck(:id).uniq
+ weekly_keep_user_count = User.where(id: pre_week_user_ids).where(last_login_on: current_week).count
+ weekly_keep_rate = format("%.2f", pre_week_user_ids.size > 0 ? weekly_keep_user_count.to_f / pre_week_user_ids.size : 0)
+
+ job_date = 1.days.ago
+ daily_statistic = DailyPlatformStatistic.find_or_initialize_by(date: job_date)
+ daily_statistic.weekly_keep_rate = weekly_keep_rate
+ daily_statistic.save
+ end
+
+ private
+
+ def current_week
+ Time.now.beginning_of_week..Time.now.end_of_day
+ end
+
+ def pre_week
+ # 7.days.ago.beginning_of_week..7.days.ago.beginning_of_week.end_of_week
+ Time.now.prev_week..Time.now.prev_week.end_of_week
+ end
+end
diff --git a/app/jobs/daily_project_statistics_job.rb b/app/jobs/daily_project_statistics_job.rb
new file mode 100644
index 000000000..3672d1924
--- /dev/null
+++ b/app/jobs/daily_project_statistics_job.rb
@@ -0,0 +1,35 @@
+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
+ 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
+ DailyProjectStatistic.create!(
+ project_id: project_id,
+ date: date,
+ score: score ,
+ visits: visits,
+ watchers: watchers,
+ praises: praises,
+ forks: forks,
+ issues: issues,
+ closed_issues: closed_issues,
+ pullrequests: pullrequests,
+ commits: commits
+ )
+ end
+ end
+end
\ No newline at end of file
diff --git a/app/jobs/delay_expired_issue_and_milestone_job.rb b/app/jobs/delay_expired_issue_and_milestone_job.rb
new file mode 100644
index 000000000..4bba7aaf1
--- /dev/null
+++ b/app/jobs/delay_expired_issue_and_milestone_job.rb
@@ -0,0 +1,16 @@
+class DelayExpiredIssueAndMilestoneJob < ApplicationJob
+ queue_as :message
+
+ def perform
+ Issue.where(due_date: Date.today + 1.days).find_each do |issue|
+ SendTemplateMessageJob.perform_later('IssueExpire', issue.id) if Site.has_notice_menu?
+ end
+ Version.where(effective_date: Date.today + 1.days).find_each do |version|
+ SendTemplateMessageJob.perform_later('ProjectMilestoneEarlyExpired', version.id) if Site.has_notice_menu?
+ end
+ Version.where(effective_date: Date.today - 1.days).find_each do |version|
+ SendTemplateMessageJob.perform_later('ProjectMilestoneExpired', version.id) if Site.has_notice_menu?
+ end
+ end
+
+end
\ No newline at end of file
diff --git a/app/jobs/delay_expired_issue_job.rb b/app/jobs/delay_expired_issue_job.rb
deleted file mode 100644
index ed390e15b..000000000
--- a/app/jobs/delay_expired_issue_job.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-class DelayExpiredIssueJob < ApplicationJob
- queue_as :message
-
- def perform
- Issue.where(due_date: Date.today + 1.days).find_each do |issue|
- SendTemplateMessageJob.perform_later('IssueExpire', issue.id) if Site.has_notice_menu?
- end
- end
-
-end
\ No newline at end of file
diff --git a/app/jobs/send_template_message_job.rb b/app/jobs/send_template_message_job.rb
index 1df1d8c7d..1b309fe35 100644
--- a/app/jobs/send_template_message_job.rb
+++ b/app/jobs/send_template_message_job.rb
@@ -221,6 +221,20 @@ class SendTemplateMessageJob < ApplicationJob
receivers_email_string, email_title, email_content = MessageTemplate::ProjectMilestone.get_email_message_content(receiver, operator, milestone)
Notice::Write::EmailCreateService.call(receivers_email_string, email_title, email_content)
end
+ when 'ProjectMilestoneExpired'
+ milestone_id = args[0]
+ milestone = Version.find_by_id(milestone_id)
+ return unless milestone.present? && milestone&.project.present?
+ receivers = User.where(id: milestone.user_id)
+ receivers_string, content, notification_url = MessageTemplate::ProjectMilestoneExpired.get_message_content(receivers, milestone)
+ Notice::Write::CreateService.call(receivers_string, content, notification_url, source, {milestone_id: milestone_id, operator_id: operator_id})
+ when 'ProjectMilestoneEarlyExpired'
+ milestone_id = args[0]
+ milestone = Version.find_by_id(milestone_id)
+ return unless milestone.present? && milestone&.project.present?
+ receivers = User.where(id: milestone.user_id)
+ receivers_string, content, notification_url = MessageTemplate::ProjectMilestoneEarlyExpired.get_message_content(receivers, milestone)
+ Notice::Write::CreateService.call(receivers_string, content, notification_url, source, {milestone_id: milestone_id, operator_id: operator_id})
when 'ProjectPraised'
operator_id, project_id = args[0], args[1]
operator = User.find_by_id(operator_id)
diff --git a/app/models/attachment.rb b/app/models/attachment.rb
index 70e1cd03a..e2b982262 100644
--- a/app/models/attachment.rb
+++ b/app/models/attachment.rb
@@ -1,46 +1,46 @@
-# == 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)
-# index_attachments_on_uuid (uuid)
-#
-
+# == 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)
+# index_attachments_on_uuid (uuid)
+#
+
diff --git a/app/models/concerns/project_operable.rb b/app/models/concerns/project_operable.rb
index 9a5efd129..34386aae2 100644
--- a/app/models/concerns/project_operable.rb
+++ b/app/models/concerns/project_operable.rb
@@ -21,68 +21,69 @@ module ProjectOperable
end
def add_member!(user_id, role_name='Developer')
- if self.owner.is_a?(Organization)
- case role_name
- when 'Manager'
- # 构建相应的团队
- team = self.owner.teams.admin.take
- if team.nil?
- team = Team.build(self.user_id, 'admin', '管理员', '', 'admin', false, false)
- gteam = $gitea_client.post_orgs_teams_by_org(self.owner.login, {body: team.to_gitea_hash.to_json}) rescue nil
- team.update_attributes!({gtid: gteam["id"]}) unless gteam.nil?
- end
-
- # 设置项目在团队中的访问权限
- team_project = TeamProject.build(self.user_id, team.id, self.id)
- tp_result = $gitea_client.put_teams_repos_by_id_org_repo(team.gtid, self.owner.login, self.identifier) rescue nil
-
- # 新增对应的团队成员
- team_user = TeamUser.build(self.user_id, user_id, team.id)
- $gitea_client.put_teams_members_by_id_username(team&.gtid, team_user.user&.login) rescue nil # 新增新的
-
- # 确保组织成员中有该用户
- OrganizationUser.build(self.user_id, user_id)
- when 'Developer'
- # 构建相应的团队
- team = self.owner.teams.write.take
- if team.nil?
- team = Team.build(self.user_id, 'developer', '开发者', '', 'write', false, false)
- gteam = $gitea_client.post_orgs_teams_by_org(self.owner.login, {body: team.to_gitea_hash.to_json}) rescue nil
- team.update_attributes!({gtid: gteam["id"]}) unless gteam.nil?
- end
-
- # 设置项目在团队中的访问权限
- team_project = TeamProject.build(self.user_id, team.id, self.id)
- tp_result = $gitea_client.put_teams_repos_by_id_org_repo(team.gtid, self.owner.login, self.identifier) rescue nil
-
- # 新增对应的团队成员
- team_user = TeamUser.build(self.user_id, user_id, team.id)
- $gitea_client.put_teams_members_by_id_username(team&.gtid, team_user.user&.login) rescue nil # 新增新的
-
- # 确保组织成员中有该用户
- OrganizationUser.build(self.user_id, user_id)
- when 'Reporter'
- # 构建相应的团队
- team = self.owner.teams.read.take
- if team.nil?
- team = Team.build(self.user_id, 'reporter', '报告者', '', 'read', false, false)
- gteam = $gitea_client.post_orgs_teams_by_org(self.owner.login, {body: team.to_gitea_hash.to_json}) rescue nil
- team.update_attributes!({gtid: gteam["id"]}) unless gteam.nil?
- end
-
- # 设置项目在团队中的访问权限
- team_project = TeamProject.build(self.user_id, team.id, self.id)
- tp_result = $gitea_client.put_teams_repos_by_id_org_repo(team.gtid, self.owner.login, self.identifier) rescue nil
-
- # 新增对应的团队成员
- team_user = TeamUser.build(self.user_id, user_id, team.id)
- $gitea_client.put_teams_members_by_id_username(team&.gtid, team_user.user&.login) rescue nil # 新增新的
-
- # 确保组织成员中有该用户
- OrganizationUser.build(self.user_id, user_id)
- end
- end
- member = members.create!(user_id: user_id, team_user_id: team_user&.id)
+ # if self.owner.is_a?(Organization)
+ # case role_name
+ # when 'Manager'
+ # # 构建相应的团队
+ # team = self.owner.teams.admin.take
+ # if team.nil?
+ # team = Team.build(self.user_id, 'admin', '管理员', '', 'admin', false, false)
+ # gteam = $gitea_client.post_orgs_teams_by_org(self.owner.login, {body: team.to_gitea_hash.to_json}) rescue nil
+ # team.update_attributes!({gtid: gteam["id"]}) unless gteam.nil?
+ # end
+ #
+ # # 设置项目在团队中的访问权限
+ # team_project = TeamProject.build(self.user_id, team.id, self.id)
+ # tp_result = $gitea_client.put_teams_repos_by_id_org_repo(team.gtid, self.owner.login, self.identifier) rescue nil
+ #
+ # # 新增对应的团队成员
+ # team_user = TeamUser.build(self.user_id, user_id, team.id)
+ # $gitea_client.put_teams_members_by_id_username(team&.gtid, team_user.user&.login) rescue nil # 新增新的
+ #
+ # # 确保组织成员中有该用户
+ # OrganizationUser.build(self.user_id, user_id)
+ # when 'Developer'
+ # # 构建相应的团队
+ # team = self.owner.teams.write.take
+ # if team.nil?
+ # team = Team.build(self.user_id, 'developer', '开发者', '', 'write', false, false)
+ # gteam = $gitea_client.post_orgs_teams_by_org(self.owner.login, {body: team.to_gitea_hash.to_json}) rescue nil
+ # team.update_attributes!({gtid: gteam["id"]}) unless gteam.nil?
+ # end
+ #
+ # # 设置项目在团队中的访问权限
+ # team_project = TeamProject.build(self.user_id, team.id, self.id)
+ # tp_result = $gitea_client.put_teams_repos_by_id_org_repo(team.gtid, self.owner.login, self.identifier) rescue nil
+ #
+ # # 新增对应的团队成员
+ # team_user = TeamUser.build(self.user_id, user_id, team.id)
+ # $gitea_client.put_teams_members_by_id_username(team&.gtid, team_user.user&.login) rescue nil # 新增新的
+ #
+ # # 确保组织成员中有该用户
+ # OrganizationUser.build(self.user_id, user_id)
+ # when 'Reporter'
+ # # 构建相应的团队
+ # team = self.owner.teams.read.take
+ # if team.nil?
+ # team = Team.build(self.user_id, 'reporter', '报告者', '', 'read', false, false)
+ # gteam = $gitea_client.post_orgs_teams_by_org(self.owner.login, {body: team.to_gitea_hash.to_json}) rescue nil
+ # team.update_attributes!({gtid: gteam["id"]}) unless gteam.nil?
+ # end
+ #
+ # # 设置项目在团队中的访问权限
+ # team_project = TeamProject.build(self.user_id, team.id, self.id)
+ # tp_result = $gitea_client.put_teams_repos_by_id_org_repo(team.gtid, self.owner.login, self.identifier) rescue nil
+ #
+ # # 新增对应的团队成员
+ # team_user = TeamUser.build(self.user_id, user_id, team.id)
+ # $gitea_client.put_teams_members_by_id_username(team&.gtid, team_user.user&.login) rescue nil # 新增新的
+ #
+ # # 确保组织成员中有该用户
+ # OrganizationUser.build(self.user_id, user_id)
+ # end
+ # end
+ # member = members.create!(user_id: user_id, team_user_id: team_user&.id)
+ member = members.create!(user_id: user_id)
set_developer_role(member, role_name)
end
@@ -116,71 +117,71 @@ module ProjectOperable
def change_member_role!(user_id, role)
member = self.member(user_id)
# 所有者为组织,并且该用户属于组织成员
- if self.owner.is_a?(Organization) && member.team_user.present?
- case role&.name
- when 'Manager'
- # 构建相应的团队
- team = self.owner.teams.admin.take
- if team.nil?
- team = Team.build(self.user_id, 'admin', '管理员', '', 'admin', false, false)
- gteam = $gitea_client.post_orgs_teams_by_org(self.owner.login, {body: team.to_gitea_hash.to_json}) rescue nil
- team.update_attributes!({gtid: gteam["id"]}) unless gteam.nil?
- end
-
- # 设置项目在团队中的访问权限
- team_project = TeamProject.build(self.user_id, team.id, self.id)
- tp_result = $gitea_client.put_teams_repos_by_id_org_repo(team.gtid, self.owner.login, self.identifier) rescue nil
-
- # 更改对应的团队成员
- team_user = member.team_user
- $gitea_client.delete_teams_members_by_id_username(team_user.team.gtid, team_user.user&.login) rescue nil # 移除旧的
- $gitea_client.put_teams_members_by_id_username(team&.gtid, team_user.user&.login) rescue nil # 新增新的
- team_user.update_attributes!({team_id: team.id}) unless team.team_users.exists?(user_id: member.user_id)
-
- # 确保组织成员中有该用户
- OrganizationUser.build(self.user_id, user_id)
- when 'Developer'
- # 构建相应的团队
- team = self.owner.teams.write.take
- if team.nil?
- team = Team.build(self.user_id, 'developer', '开发者', '', 'write', false, false)
- gteam = $gitea_client.post_orgs_teams_by_org(self.owner.login, {body: team.to_gitea_hash.to_json}) rescue nil
- team.update_attributes!({gtid: gteam["id"]}) unless gteam.nil?
- end
- # 设置项目在团队中的访问权限
- team_project = TeamProject.build(self.user_id, team.id, self.id)
- $gitea_client.put_teams_repos_by_id_org_repo(team.gtid, self.owner.login, self.identifier) rescue nil
-
- # 更改对应的团队成员
- team_user = member.team_user
- $gitea_client.delete_teams_members_by_id_username(team_user.team.gtid, team_user.user&.login) rescue nil # 移除旧的
- $gitea_client.put_teams_members_by_id_username(team&.gtid, team_user.user&.login) rescue nil # 新增新的
- team_user.update_attributes!({team_id: team.id}) unless team.team_users.exists?(user_id: member.user_id)
-
- OrganizationUser.build(self.user_id, user_id)
- when 'Reporter'
- # 构建相应的团队
- team = self.owner.teams.read.take
- if team.nil?
- team = Team.build(self.user_id, 'reporter', '报告者', '', 'read', false, false)
- gteam = $gitea_client.post_orgs_teams_by_org(self.owner.login, {body: team.to_gitea_hash.to_json}) rescue nil
- team.update_attributes!({gtid: gteam["id"]}) unless gteam.nil?
- end
-
- # 设置项目在团队中的访问权限
- team_project = TeamProject.build(self.user_id, team.id, self.id)
- tp_result = $gitea_client.put_teams_repos_by_id_org_repo(team.gtid, self.owner.login, self.identifier) rescue nil
-
- # 更改对应的团队成员
- team_user = member.team_user
- $gitea_client.delete_teams_members_by_id_username(team_user.team.gtid, team_user.user&.login) rescue nil # 移除旧的
- $gitea_client.put_teams_members_by_id_username(team&.gtid, team_user.user&.login) rescue nil # 新增新的
- team_user.update_attributes!({team_id: team.id}) unless team.team_users.exists?(user_id: member.user_id)
-
- # 确保组织成员中有该用户
- OrganizationUser.build(self.user_id, user_id)
- end
- end
+ # if self.owner.is_a?(Organization) && member.team_user.present?
+ # case role&.name
+ # when 'Manager'
+ # # 构建相应的团队
+ # team = self.owner.teams.admin.take
+ # if team.nil?
+ # team = Team.build(self.user_id, 'admin', '管理员', '', 'admin', false, false)
+ # gteam = $gitea_client.post_orgs_teams_by_org(self.owner.login, {body: team.to_gitea_hash.to_json}) rescue nil
+ # team.update_attributes!({gtid: gteam["id"]}) unless gteam.nil?
+ # end
+ #
+ # # 设置项目在团队中的访问权限
+ # team_project = TeamProject.build(self.user_id, team.id, self.id)
+ # tp_result = $gitea_client.put_teams_repos_by_id_org_repo(team.gtid, self.owner.login, self.identifier) rescue nil
+ #
+ # # 更改对应的团队成员
+ # team_user = member.team_user
+ # $gitea_client.delete_teams_members_by_id_username(team_user.team.gtid, team_user.user&.login) rescue nil # 移除旧的
+ # $gitea_client.put_teams_members_by_id_username(team&.gtid, team_user.user&.login) rescue nil # 新增新的
+ # team_user.update_attributes!({team_id: team.id}) unless team.team_users.exists?(user_id: member.user_id)
+ #
+ # # 确保组织成员中有该用户
+ # OrganizationUser.build(self.user_id, user_id)
+ # when 'Developer'
+ # # 构建相应的团队
+ # team = self.owner.teams.write.take
+ # if team.nil?
+ # team = Team.build(self.user_id, 'developer', '开发者', '', 'write', false, false)
+ # gteam = $gitea_client.post_orgs_teams_by_org(self.owner.login, {body: team.to_gitea_hash.to_json}) rescue nil
+ # team.update_attributes!({gtid: gteam["id"]}) unless gteam.nil?
+ # end
+ # # 设置项目在团队中的访问权限
+ # team_project = TeamProject.build(self.user_id, team.id, self.id)
+ # $gitea_client.put_teams_repos_by_id_org_repo(team.gtid, self.owner.login, self.identifier) rescue nil
+ #
+ # # 更改对应的团队成员
+ # team_user = member.team_user
+ # $gitea_client.delete_teams_members_by_id_username(team_user.team.gtid, team_user.user&.login) rescue nil # 移除旧的
+ # $gitea_client.put_teams_members_by_id_username(team&.gtid, team_user.user&.login) rescue nil # 新增新的
+ # team_user.update_attributes!({team_id: team.id}) unless team.team_users.exists?(user_id: member.user_id)
+ #
+ # OrganizationUser.build(self.user_id, user_id)
+ # when 'Reporter'
+ # # 构建相应的团队
+ # team = self.owner.teams.read.take
+ # if team.nil?
+ # team = Team.build(self.user_id, 'reporter', '报告者', '', 'read', false, false)
+ # gteam = $gitea_client.post_orgs_teams_by_org(self.owner.login, {body: team.to_gitea_hash.to_json}) rescue nil
+ # team.update_attributes!({gtid: gteam["id"]}) unless gteam.nil?
+ # end
+ #
+ # # 设置项目在团队中的访问权限
+ # team_project = TeamProject.build(self.user_id, team.id, self.id)
+ # tp_result = $gitea_client.put_teams_repos_by_id_org_repo(team.gtid, self.owner.login, self.identifier) rescue nil
+ #
+ # # 更改对应的团队成员
+ # team_user = member.team_user
+ # $gitea_client.delete_teams_members_by_id_username(team_user.team.gtid, team_user.user&.login) rescue nil # 移除旧的
+ # $gitea_client.put_teams_members_by_id_username(team&.gtid, team_user.user&.login) rescue nil # 新增新的
+ # team_user.update_attributes!({team_id: team.id}) unless team.team_users.exists?(user_id: member.user_id)
+ #
+ # # 确保组织成员中有该用户
+ # OrganizationUser.build(self.user_id, user_id)
+ # end
+ # end
member.member_roles.last.update_attributes!(role: role)
end
diff --git a/app/models/daily_platform_statistic.rb b/app/models/daily_platform_statistic.rb
new file mode 100644
index 000000000..a904d9b1e
--- /dev/null
+++ b/app/models/daily_platform_statistic.rb
@@ -0,0 +1,24 @@
+# == Schema Information
+#
+# Table name: daily_platform_statistics
+#
+# id :integer not null, primary key
+# date :date
+# pv :integer default("0")
+# visitor :integer default("0")
+# ip :integer default("0")
+# weekly_keep_rate :float(24) default("0")
+# source_through :float(24) default("0")
+# source_link :float(24) default("0")
+# source_search :float(24) default("0")
+# source_custom :float(24) default("0")
+# created_at :datetime not null
+# updated_at :datetime not null
+#
+# Indexes
+#
+# index_daily_platform_statistics_on_date (date) UNIQUE
+#
+
+class DailyPlatformStatistic < ApplicationRecord
+end
diff --git a/app/models/daily_project_statistic.rb b/app/models/daily_project_statistic.rb
new file mode 100644
index 000000000..ffe51bdb3
--- /dev/null
+++ b/app/models/daily_project_statistic.rb
@@ -0,0 +1,30 @@
+# == Schema Information
+#
+# Table name: daily_project_statistics
+#
+# 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
+#
+# 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/models/issue.rb b/app/models/issue.rb
index 028ceb930..622aa4ae0 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -105,7 +105,7 @@ class Issue < ApplicationRecord
scope :opened, ->{where.not(status_id: 5)}
after_create :incre_project_common, :incre_user_statistic, :incre_platform_statistic
before_save :check_pm_and_update_due_date
- after_save :change_versions_count, :send_update_message_to_notice_system, :associate_attachment_container, :generate_uuid
+ after_save :incre_or_decre_closed_issues_count, :change_versions_count, :send_update_message_to_notice_system, :associate_attachment_container, :generate_uuid
after_destroy :update_closed_issues_count_in_project!, :decre_project_common, :decre_user_statistic, :decre_platform_statistic
def check_pm_and_update_due_date
@@ -126,20 +126,35 @@ class Issue < ApplicationRecord
end
end
+ def is_issuely_issue?
+ self.issue_classify.nil? || self.issue_classify == 'issue'
+ end
+
+ def incre_or_decre_closed_issues_count
+ if previous_changes[:status_id].present? && is_issuely_issue?
+ 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)
+ CacheAsyncSetJob.perform_later('project_common_service', {issues: 1}, self.project_id) if is_issuely_issue?
end
def decre_project_common
- CacheAsyncSetJob.perform_later('project_common_service', {issues: -1}, self.project_id)
+ CacheAsyncSetJob.perform_later('project_common_service', {issues: -1}, self.project_id) if is_issuely_issue?
end
def incre_user_statistic
- CacheAsyncSetJob.perform_later('user_statistic_service', {issue_count: 1}, self.author_id)
+ CacheAsyncSetJob.perform_later('user_statistic_service', {issue_count: 1}, self.author_id) if is_issuely_issue?
end
def decre_user_statistic
- CacheAsyncSetJob.perform_later('user_statistic_service', {issue_count: -1}, self.author_id)
+ CacheAsyncSetJob.perform_later('user_statistic_service', {issue_count: -1}, self.author_id) if is_issuely_issue?
end
def refresh_root_issue_count
@@ -150,11 +165,12 @@ class Issue < ApplicationRecord
end
def incre_platform_statistic
- CacheAsyncSetJob.perform_later('platform_statistic_service', {issue_count: 1})
+ CacheAsyncSetJob.perform_later('platform_statistic_service', {issue_count: 1}) if is_issuely_issue?
end
def decre_platform_statistic
- CacheAsyncSetJob.perform_later('platform_statistic_service', {issue_count: -1})
+ CacheAsyncSetJob.perform_later('platform_statistic_service', {issue_count: -1}) if is_issuely_issue?
+ end
end
def get_assign_user
diff --git a/app/models/message_template.rb b/app/models/message_template.rb
index 7ab7fdad8..75d64fa95 100644
--- a/app/models/message_template.rb
+++ b/app/models/message_template.rb
@@ -52,6 +52,8 @@ class MessageTemplate < ApplicationRecord
self.create(type: 'MessageTemplate::ProjectMilestone', sys_notice: '{nickname1}在 {nickname2}/{repository} 创建了一个里程碑:{name}', notification_url: '{baseurl}/{owner}/{identifier}/milestones/{id}', email: email_html, email_title: "#{PLATFORM}: {nickname1} 在 {nickname2}/{repository} 新建了一个里程碑")
email_html = File.read("#{email_template_html_dir}/project_milestone_completed.html")
self.create(type: 'MessageTemplate::ProjectMilestoneCompleted', sys_notice: '在 {nickname}/{repository} 仓库,里程碑 {name} 的完成度已达到100%', notification_url: '{baseurl}/{owner}/{identifier}/milestones/{id}', email: email_html, email_title: "#{PLATFORM}: 仓库 {nickname}/{repository} 有里程碑已完成")
+ self.create(type: 'MessageTemplate::ProjectMilestoneEarlyExpired', sys_notice: '您创建的里程碑 {name} 已临近截止日期,请尽快处理.', notification_url: '{baseurl}/{owner}/{identifier}/milestones/{id}')
+ self.create(type: 'MessageTemplate::ProjectMilestoneExpired', sys_notice: '您创建的里程碑 {name} 已逾期,请及时更新进度或联系项目团队.', notification_url: '{baseurl}/{owner}/{identifier}/milestones/{id}')
self.create(type: 'MessageTemplate::ProjectPraised', sys_notice: '{nickname1} 点赞了你管理的仓库 {nickname2}/{repository}', notification_url: '{baseurl}/{login}')
self.create(type: 'MessageTemplate::ProjectOpenDevOps', sys_notice: '您的仓库 {repository} 已成功开通引擎服务,可通过简单的节点编排完成自动化集成与部署。欢迎体验!', notification_url: '{baseurl}/{owner}/{identifier}/devops')
email_html = File.read("#{email_template_html_dir}/project_pull_request.html")
diff --git a/app/models/message_template/project_milestone_early_expired.rb b/app/models/message_template/project_milestone_early_expired.rb
new file mode 100644
index 000000000..5539fc362
--- /dev/null
+++ b/app/models/message_template/project_milestone_early_expired.rb
@@ -0,0 +1,70 @@
+# == Schema Information
+#
+# Table name: message_templates
+#
+# id :integer not null, primary key
+# type :string(255)
+# sys_notice :text(65535)
+# email :text(65535)
+# created_at :datetime not null
+# updated_at :datetime not null
+# notification_url :string(255)
+# email_title :string(255)
+#
+
+# 我管理的仓库有里程碑完成
+class MessageTemplate::ProjectMilestoneEarlyExpired < MessageTemplate
+
+ # MessageTemplate::ProjectMilestoneEarlyExpired.get_message_content(User.where(login: 'yystopf'), Version.find(7))
+ def self.get_message_content(receivers, milestone)
+ receivers.each do |receiver|
+ if receiver.user_template_message_setting.present?
+ send_setting = receiver.user_template_message_setting.notification_body["ManageProject::MilestoneEarlyExpired"]
+ send_setting = send_setting.nil? ? UserTemplateMessageSetting.init_notification_body["ManageProject::MilestoneEarlyExpired"] : send_setting
+ receivers = receivers.where.not(id: receiver.id) unless send_setting
+ end
+ end
+ return '', '', '' if receivers.blank?
+ project = milestone&.project
+ owner = project&.owner
+ content = sys_notice.gsub('{nickname}', owner&.real_name).gsub('{repository}', project&.name).gsub('{name}', milestone&.name)
+ url = notification_url.gsub('{owner}', owner&.login).gsub('{identifier}', project&.identifier).gsub('{id}', milestone&.id.to_s)
+
+ return receivers_string(receivers), content, url
+ rescue => e
+ Rails.logger.info("MessageTemplate::MilestoneEarlyExpired.get_message_content [ERROR] #{e}")
+ return '', '', ''
+ end
+
+ def self.get_email_message_content(receiver, milestone)
+ if receiver.user_template_message_setting.present?
+ send_setting = receiver.user_template_message_setting.email_body["ManageProject::MilestoneEarlyExpired"]
+ send_setting = send_setting.nil? ? UserTemplateMessageSetting.init_email_body["ManageProject::MilestoneEarlyExpired"] : send_setting
+ return '', '', '' unless send_setting
+ project = milestone&.project
+ owner = project&.owner
+ title = email_title
+ title.gsub!('{nickname}', owner&.real_name)
+ title.gsub!('{repository}', project&.name)
+
+ content = email
+ content.gsub!('{receiver}', receiver&.real_name)
+ content.gsub!('{baseurl}', base_url)
+ content.gsub!('{nickname}', owner&.real_name)
+ content.gsub!('{repository}', project&.name)
+ content.gsub!('{login}', owner&.login)
+ content.gsub!('{identifier}', project&.identifier)
+ content.gsub!('{id}', milestone&.id.to_s)
+ content.gsub!('{name}', milestone&.name)
+ content.gsub!('{platform}', PLATFORM)
+
+ return receiver&.mail, title, content
+ else
+ return '', '', ''
+ end
+
+ rescue => e
+ Rails.logger.info("MessageTemplate::MilestoneEarlyExpired.get_email_message_content [ERROR] #{e}")
+ return '', '', ''
+ end
+end
diff --git a/app/models/message_template/project_milestone_expired.rb b/app/models/message_template/project_milestone_expired.rb
new file mode 100644
index 000000000..de6b8c10c
--- /dev/null
+++ b/app/models/message_template/project_milestone_expired.rb
@@ -0,0 +1,70 @@
+# == Schema Information
+#
+# Table name: message_templates
+#
+# id :integer not null, primary key
+# type :string(255)
+# sys_notice :text(65535)
+# email :text(65535)
+# created_at :datetime not null
+# updated_at :datetime not null
+# notification_url :string(255)
+# email_title :string(255)
+#
+
+# 我管理的仓库有里程碑完成
+class MessageTemplate::ProjectMilestoneExpired < MessageTemplate
+
+ # MessageTemplate::ProjectMilestoneExpired.get_message_content(User.where(login: 'yystopf'), Version.find(7))
+ def self.get_message_content(receivers, milestone)
+ receivers.each do |receiver|
+ if receiver.user_template_message_setting.present?
+ send_setting = receiver.user_template_message_setting.notification_body["ManageProject::MilestoneExpired"]
+ send_setting = send_setting.nil? ? UserTemplateMessageSetting.init_notification_body["ManageProject::MilestoneExpired"] : send_setting
+ receivers = receivers.where.not(id: receiver.id) unless send_setting
+ end
+ end
+ return '', '', '' if receivers.blank?
+ project = milestone&.project
+ owner = project&.owner
+ content = sys_notice.gsub('{nickname}', owner&.real_name).gsub('{repository}', project&.name).gsub('{name}', milestone&.name)
+ url = notification_url.gsub('{owner}', owner&.login).gsub('{identifier}', project&.identifier).gsub('{id}', milestone&.id.to_s)
+
+ return receivers_string(receivers), content, url
+ rescue => e
+ Rails.logger.info("MessageTemplate::ProjectMilestoneExpired.get_message_content [ERROR] #{e}")
+ return '', '', ''
+ end
+
+ def self.get_email_message_content(receiver, milestone)
+ if receiver.user_template_message_setting.present?
+ send_setting = receiver.user_template_message_setting.email_body["ManageProject::MilestoneExpired"]
+ send_setting = send_setting.nil? ? UserTemplateMessageSetting.init_email_body["ManageProject::MilestoneExpired"] : send_setting
+ return '', '', '' unless send_setting
+ project = milestone&.project
+ owner = project&.owner
+ title = email_title
+ title.gsub!('{nickname}', owner&.real_name)
+ title.gsub!('{repository}', project&.name)
+
+ content = email
+ content.gsub!('{receiver}', receiver&.real_name)
+ content.gsub!('{baseurl}', base_url)
+ content.gsub!('{nickname}', owner&.real_name)
+ content.gsub!('{repository}', project&.name)
+ content.gsub!('{login}', owner&.login)
+ content.gsub!('{identifier}', project&.identifier)
+ content.gsub!('{id}', milestone&.id.to_s)
+ content.gsub!('{name}', milestone&.name)
+ content.gsub!('{platform}', PLATFORM)
+
+ return receiver&.mail, title, content
+ else
+ return '', '', ''
+ end
+
+ rescue => e
+ Rails.logger.info("MessageTemplate::ProjectMilestoneExpired.get_email_message_content [ERROR] #{e}")
+ return '', '', ''
+ end
+end
diff --git a/app/models/organization.rb b/app/models/organization.rb
index cb829626e..237efbfe9 100644
--- a/app/models/organization.rb
+++ b/app/models/organization.rb
@@ -64,7 +64,7 @@
class Organization < Owner
alias_attribute :name, :login
- NAME_REGEX = /^(?!_)(?!.*?_$)[a-zA-Z0-9_-]+$/ #只含有数字、字母、下划线不能以下划线开头和结尾
+ NAME_REGEX = /^[a-zA-Z0-9]+([-_.][a-zA-Z0-9]+)*$/ #只含有数字、字母、下划线不能以下划线开头和结尾
default_scope { where(type: "Organization") }
@@ -79,7 +79,7 @@ class Organization < Owner
validates :login, presence: true
validates_uniqueness_of :login, :if => Proc.new { |user| user.login_changed? && user.login.present? }, case_sensitive: false
- validates :login, format: { with: NAME_REGEX, multiline: true, message: "只能含有数字、字母、下划线且不能以下划线开头和结尾" }
+ validates :login, format: { with: NAME_REGEX, multiline: true, message: "只能以数字或字母开头,仅支持横杠、下划线、点三种符号,不允许符号连续排列,长度4-50个字符" }
delegate :description, :website, :location, :repo_admin_change_team_access, :recommend,
:visibility, :max_repo_creation, :num_projects, :num_users, :num_teams,
diff --git a/app/models/page.rb b/app/models/page.rb
index 57a30acad..1c606760e 100644
--- a/app/models/page.rb
+++ b/app/models/page.rb
@@ -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
diff --git a/app/models/project.rb b/app/models/project.rb
index 15eb36493..62b76dae2 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -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
diff --git a/app/models/user.rb b/app/models/user.rb
index 8f1e29547..afe817d33 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -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]) }
@@ -465,7 +465,7 @@ class User < Owner
$gitea_client.delete_users_tokens_by_username_token(self.login, e["name"], {query: {sudo: self.login} })
}
end
- new_result = $gitea_client.post_users_tokens_by_username(self.login, { query: {sudo: self.login}, body:{ name: self.login} })
+ new_result = $gitea_client.post_users_tokens_by_username(self.login, { query: {sudo: self.login}, body:{ name: "#{self.login}-#{SecureRandom.hex(6)}", scopes: ["all"]}.to_json })
if new_result["sha1"].present?
update(gitea_token: new_result["sha1"])
end
@@ -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
diff --git a/app/models/user_template_message_setting.rb b/app/models/user_template_message_setting.rb
index 49db51d4d..7e855b768 100644
--- a/app/models/user_template_message_setting.rb
+++ b/app/models/user_template_message_setting.rb
@@ -44,6 +44,8 @@ class UserTemplateMessageSetting < ApplicationRecord
"ManageProject::Forked": true,
"ManageProject::Milestone": true,
"ManageProject::MilestoneCompleted": true,
+ "ManageProject::MilestoneExpired": true,
+ "ManageProject::MilestoneEarlyExpired": true,
}.stringify_keys!
end
@@ -65,6 +67,8 @@ class UserTemplateMessageSetting < ApplicationRecord
"ManageProject::Forked": false,
"ManageProject::Milestone": false,
"ManageProject::MilestoneCompleted": false,
+ "ManageProject::MilestoneExpired": false,
+ "ManageProject::MilestoneEarlyExpired": false,
}.stringify_keys!
end
diff --git a/app/models/version.rb b/app/models/version.rb
index ec2ad68cd..871f63dfd 100644
--- a/app/models/version.rb
+++ b/app/models/version.rb
@@ -68,5 +68,7 @@ class Version < ApplicationRecord
def send_update_message_to_notice_system
SendTemplateMessageJob.perform_later('ProjectMilestoneCompleted', self.id) if Site.has_notice_menu? && self.issue_percent == 1.0
+ SendTemplateMessageJob.perform_later('ProjectMilestoneEarlyExpired', self.id) if Site.has_notice_menu? && self.effective_date == Date.today + 1.days
+ SendTemplateMessageJob.perform_later('ProjectMilestoneExpired', self.id) if Site.has_notice_menu? && self.effective_date == Date.today - 1.days
end
end
diff --git a/app/services/api/v1/issues/list_service.rb b/app/services/api/v1/issues/list_service.rb
index 0878fb908..2ceb5bae3 100644
--- a/app/services/api/v1/issues/list_service.rb
+++ b/app/services/api/v1/issues/list_service.rb
@@ -76,10 +76,22 @@ 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
#pm相关
# root_id# -1 查一级目录
@@ -102,7 +114,13 @@ class Api::V1::Issues::ListService < ApplicationService
issues = issues.where(pm_sprint_id: pm_sprint_id) if pm_sprint_id.present?
# 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'
diff --git a/app/services/api/v1/projects/actions/runs/job_show_service.rb b/app/services/api/v1/projects/actions/runs/job_show_service.rb
new file mode 100644
index 000000000..e80e882be
--- /dev/null
+++ b/app/services/api/v1/projects/actions/runs/job_show_service.rb
@@ -0,0 +1,42 @@
+class Api::V1::Projects::Actions::Runs::JobShowService < ApplicationService
+ include ActiveModel::Model
+
+ attr_reader :project, :token, :owner, :repo, :run, :job, :log_cursors
+ attr_accessor :gitea_data
+
+ validates :run, :job, :log_cursors, presence: true
+
+ def initialize(project, run, job, log_cursors, token = nil)
+ @project = project
+ @owner = project&.owner.login
+ @repo = project&.identifier
+ @run = run
+ @job = job
+ @log_cursors = log_cursors
+ @token = token
+ end
+
+ def call
+ raise Error, errors.full_messages.join(",") unless valid?
+ load_gitea_data
+
+ @gitea_data
+ end
+
+ private
+ def request_params
+ {
+ access_token: token
+ }
+ end
+
+ def request_body
+ {
+ logCursors: log_cursors
+ }
+ end
+
+ def load_gitea_data
+ @gitea_data = $gitea_hat_client.post_repos_actions_runs_jobs_by_owner_repo_run_job(owner, repo, run, job, {query: request_params, body: request_body.to_json})
+ end
+end
\ No newline at end of file
diff --git a/app/services/api/v1/projects/actions/runs/list_service.rb b/app/services/api/v1/projects/actions/runs/list_service.rb
new file mode 100644
index 000000000..5889518ce
--- /dev/null
+++ b/app/services/api/v1/projects/actions/runs/list_service.rb
@@ -0,0 +1,40 @@
+class Api::V1::Projects::Actions::Runs::ListService < ApplicationService
+ include ActiveModel::Model
+
+ attr_reader :project, :token, :owner, :repo, :workflow, :page, :limit
+ attr_accessor :gitea_data
+
+ validates :workflow, presence: true
+
+ def initialize(project, params, token =nil)
+ @project = project
+ @owner = project&.owner.login
+ @repo = project&.identifier
+ @workflow = params[:workflow]
+ @page = params[:page] || 1
+ @limit = params[:limit] || 15
+ @token = token
+ end
+
+ def call
+ raise Error, errors.full_messages.join(",") unless valid?
+ load_gitea_data
+
+ @gitea_data
+ end
+
+ private
+ def request_params
+ {
+ access_token: token,
+ workflow: workflow,
+ page: page,
+ limit: limit
+ }
+ end
+
+ def load_gitea_data
+ @gitea_data = $gitea_hat_client.get_repos_actions_by_owner_repo(owner, repo, {query: request_params}) rescue nil
+ raise Error, '获取流水线执行记录失败!' unless @gitea_data.is_a?(Hash)
+ end
+end
\ No newline at end of file
diff --git a/app/services/api/v1/projects/branches/list_service.rb b/app/services/api/v1/projects/branches/list_service.rb
index 590c4884f..6980b71ea 100644
--- a/app/services/api/v1/projects/branches/list_service.rb
+++ b/app/services/api/v1/projects/branches/list_service.rb
@@ -1,6 +1,6 @@
class Api::V1::Projects::Branches::ListService < ApplicationService
- attr_accessor :project, :token, :owner, :repo, :name, :page, :limit
+ attr_accessor :project, :token, :owner, :repo, :name, :state, :page, :limit
attr_accessor :gitea_data, :gitea_repo_data
def initialize(project, params, token=nil)
@@ -9,6 +9,7 @@ class Api::V1::Projects::Branches::ListService < ApplicationService
@repo = project&.identifier
@token = token
@name = params[:name]
+ @state = params[:state]
@page = params[:page]
@limit = params[:limit]
end
@@ -18,7 +19,6 @@ class Api::V1::Projects::Branches::ListService < ApplicationService
load_default_branch
@gitea_data[:default_branch] = @gitea_repo_data["default_branch"]
-
@gitea_data
end
@@ -30,7 +30,8 @@ class Api::V1::Projects::Branches::ListService < ApplicationService
limit: limit
}
params.merge!({name: name}) if name.present?
-
+ params.merge!({state: state}) if state.present?
+
params
end
diff --git a/app/services/api/v1/projects/branches/restore_service.rb b/app/services/api/v1/projects/branches/restore_service.rb
new file mode 100644
index 000000000..fbd6220ed
--- /dev/null
+++ b/app/services/api/v1/projects/branches/restore_service.rb
@@ -0,0 +1,47 @@
+class Api::V1::Projects::Branches::RestoreService < ApplicationService
+
+ include ActiveModel::Model
+
+ attr_accessor :project, :token, :owner, :repo, :branch_id, :branch_name
+ attr_accessor :gitea_data
+
+ validates :branch_id, :branch_name, presence: true
+
+ def initialize(project, branch_id, branch_name, token= nil)
+ @project = project
+ @owner = project&.owner&.login
+ @repo = project&.identifier
+ @branch_id = branch_id
+ @branch_name = branch_name
+ @token = token
+ end
+
+ def call
+ raise Error, errors.full_messages.join(",") unless valid?
+ excute_data_to_gitea
+
+ true
+ end
+
+ private
+ def request_params
+ {
+ access_token: token
+ }
+ end
+
+ def request_body
+ {
+ branch_id: branch_id,
+ name: branch_name,
+ }
+ end
+
+ def excute_data_to_gitea
+ begin
+ @gitea_data = $gitea_hat_client.post_repos_branches_restore_by_owner_repo(owner, repo, {query: request_params, body: request_body.to_json})
+ rescue => e
+ raise Error, '恢复分支失败!'
+ end
+ end
+end
\ No newline at end of file
diff --git a/app/services/api/v1/projects/commits/recent_service.rb b/app/services/api/v1/projects/commits/recent_service.rb
new file mode 100644
index 000000000..fa4f65b43
--- /dev/null
+++ b/app/services/api/v1/projects/commits/recent_service.rb
@@ -0,0 +1,37 @@
+class Api::V1::Projects::Commits::RecentService < ApplicationService
+
+ attr_reader :project, :page, :limit, :owner, :repo, :token
+ attr_accessor :gitea_data
+
+ def initialize(project, params, token=nil)
+ @project = project
+ @page = params[:page] || 1
+ @limit = params[:limit] || 15
+ @owner = project&.owner&.login
+ @repo = project&.identifier
+ @token = token
+ end
+
+ def call
+ load_gitea_data
+
+ gitea_data
+ end
+
+ private
+ def request_params
+ param = {
+ access_token: token,
+ page: page,
+ limit: limit
+ }
+
+ param
+ end
+
+ def load_gitea_data
+ @gitea_data = $gitea_hat_client.get_repos_recent_commits_by_owner_repo(owner, repo, {query: request_params}) rescue nil
+ raise Error, "获取最近提交列表失败" unless @gitea_data.is_a?(Hash)
+ end
+
+end
\ No newline at end of file
diff --git a/app/services/api/v1/projects/compare_service.rb b/app/services/api/v1/projects/compare_service.rb
index 23a248305..9e646326f 100644
--- a/app/services/api/v1/projects/compare_service.rb
+++ b/app/services/api/v1/projects/compare_service.rb
@@ -29,6 +29,6 @@ class Api::V1::Projects::CompareService < ApplicationService
end
def load_gitea_data
- @gitea_data = $gitea_client.get_repos_compare_by_owner_repo_from_to(owner, repo, from, to, {query: request_params}) rescue nil
+ @gitea_data = $gitea_hat_client.get_repos_compare_by_owner_repo_baseref_headref(owner, repo, to, from, {query: request_params}) rescue nil
end
end
\ No newline at end of file
diff --git a/app/services/baidu/tongji_service.rb b/app/services/baidu/tongji_service.rb
new file mode 100644
index 000000000..a2a4f28fc
--- /dev/null
+++ b/app/services/baidu/tongji_service.rb
@@ -0,0 +1,221 @@
+module Baidu
+ class TongjiService < ApplicationService
+ attr_reader :client_id, :client_secret, :site_id
+ # login、code、password、password_confirmation
+ def initialize
+ @client_id = "6dMO2kqKUaMZkBrMaUMxQSNAT49v0Mjq"
+ @client_secret = "qvWqF33AOmGs1tPCgsROvis9EQCuNmd3"
+ @site_id = 18657013
+ end
+
+ def call
+
+ end
+
+
+ def init_overview_data_by(start_date = nil, end_date = nil)
+ start_date = Time.now.prev_year.beginning_of_year if start_date.nil?
+ end_date = Time.now
+ Rails.logger.info("*********开始百度统计-概览:#{start_date}-#{end_date}*********")
+ sql_connection = ActiveRecord::Base.connection
+ sql_connection.begin_db_transaction
+
+ # 如果存在数据 先清空
+ # sql_connection.execute("delete from daily_platform_statistics where date between '#{start_date}' and '#{end_date}'")
+ multiple_days_data = overview_multiple_days_data(start_date, end_date)
+ if multiple_days_data.present?
+ sql = "replace into daily_platform_statistics (date,pv,visitor,ip,created_at,updated_at) values #{multiple_days_data.join(",")}"
+ sql_connection.execute(sql)
+ end
+ sql_connection.commit_db_transaction
+ Rails.logger.info("*********结束百度统计-概览:#{start_date}-#{end_date}*********")
+ end
+
+ def init_source_from_data_by(start_date = nil, end_date = nil)
+ start_date = Time.now.prev_year.beginning_of_year if start_date.nil?
+ end_date = Time.now
+ Rails.logger.info("*********开始百度统计-来源:#{start_date}-#{end_date}*********")
+ source_from_batch_add(start_date, end_date)
+ Rails.logger.info("*********结束百度统计-来源:#{start_date}-#{end_date}*********")
+ end
+
+ # 按日期获取来源数据
+ def source_from_batch_add(start_date,end_date)
+ # 补充更新开始时间的当天数据
+ source_from_by_date(start_date)
+ diff_days(start_date, end_date).times.each do |t|
+ new_start_date = start_date + (t + 1).days
+ source_from_by_date(new_start_date)
+ end
+ # 补充更新最后时间一天数据
+ source_from_by_date(end_date)
+ end
+
+ # 按天获取来源数据
+ def source_from_by_date(start_date)
+ return [] unless access_token.present? && start_date.present?
+ source_from_data = api("source/all/a", start_date, start_date, "pv_count,visitor_count,ip_count")
+ source_from = []
+ source_from_data['items'][1].each_with_index do |source, index|
+ source_from.push(((source[0].to_f / source_from_data['sum'][0][0].to_f) * 100).round(2))
+ end
+ daily_statistic = DailyPlatformStatistic.find_or_initialize_by(date: start_date)
+ daily_statistic.source_through = source_from[0]
+ daily_statistic.source_link = source_from[1]
+ daily_statistic.source_search = source_from[2]
+ daily_statistic.source_custom = source_from[3]
+ daily_statistic.save
+ end
+
+ def diff_days(start_date, end_date)
+ (end_date.beginning_of_day.to_i - start_date.beginning_of_day.to_i) / (24 * 3600)
+ end
+
+ def overview_batch_add(start_date, end_date)
+ return [] unless access_token.present? && start_date.present? && end_date.present?
+ start_date = Time.now - 1.days if start_date.strftime("%Y%m%d") == end_date.strftime("%Y%m%d")
+ overview_data = api("overview/getTimeTrendRpt", start_date, end_date, "pv_count,visitor_count,ip_count")
+ overview_data['items'][0].each_with_index do |date, index|
+ pv = overview_data['items'][1][index][0]
+ visitor = overview_data['items'][1][index][1]
+ ip = overview_data['items'][1][index][2]
+ job_date = date[0].to_s.gsub("/", "-")
+ daily_statistic = DailyPlatformStatistic.find_or_initialize_by(date: job_date)
+ daily_statistic.date = job_date
+ daily_statistic.pv = pv
+ daily_statistic.visitor = visitor
+ daily_statistic.ip = ip
+ daily_statistic.save
+ end
+ overview_data
+ end
+
+ def overview_multiple_days_data(start_date, end_date)
+ return [] unless access_token.present? && start_date.present? && end_date.present?
+ overview_data = api("overview/getTimeTrendRpt", start_date, end_date, "pv_count,visitor_count,ip_count")
+ data = []
+ created_at = Time.now.strftime("%Y-%m-%d 00:00:00")
+ overview_data['items'][0].each_with_index do |date, index|
+ pv = overview_data['items'][1][index][0]
+ visitor = overview_data['items'][1][index][1]
+ ip = overview_data['items'][1][index][2]
+ data.push("('#{date[0].to_s.gsub("/", "-")}', #{pv.to_s.gsub("--","0")}, #{visitor.to_s.gsub("--","0")}, #{ip.to_s.gsub("--","0")},\"#{created_at}\",\"#{created_at}\")")
+ end
+ data
+ end
+
+ def code_url
+ "http://openapi.baidu.com/oauth/2.0/authorize?response_type=code&client_id=#{client_id}&redirect_uri=oob&scope=basic&display=popup"
+ end
+
+ def oauth_url(code)
+ "http://openapi.baidu.com/oauth/2.0/token?grant_type=authorization_code&code=#{code}&client_id=#{client_id}&client_secret=#{client_secret}&redirect_uri=oob"
+ end
+
+ def get_access_token(code)
+ uri = URI.parse(oauth_url(code))
+ response = Net::HTTP.get_response(uri)
+ Rails.logger.info "baidu_tongji_auth response.body ===== #{response.body}"
+ if response.code.to_i == 200
+ data = JSON.parse(response.body)
+ access_token = data['access_token']
+ refresh_token = data['refresh_token']
+ expires_in = data['expires_in']
+ if access_token.present?
+ Rails.cache.write("baidu_tongji_auth/access_token", access_token, expires_in: expires_in)
+ Rails.cache.write("baidu_tongji_auth/refresh_token", refresh_token, expires_in: 1.year)
+ end
+ end
+ end
+
+ def refresh_access_token
+ url = "http://openapi.baidu.com/oauth/2.0/token?grant_type=refresh_token&refresh_token=#{refresh_token}&client_id=#{client_id}&client_secret=#{client_secret}"
+ uri = URI.parse(url)
+ response = Net::HTTP.get_response(uri)
+ Rails.logger.info "baidu_tongji_auth response.body ===== #{response.body}"
+ if response.code.to_i == 200
+ data = JSON.parse(response.body)
+ access_token = data['access_token']
+ refresh_token = data['refresh_token']
+ expires_in = data['expires_in']
+ if access_token.present?
+ Rails.cache.write("baidu_tongji_auth/access_token", access_token, expires_in: expires_in)
+ Rails.cache.write("baidu_tongji_auth/refresh_token", refresh_token, expires_in: 1.year)
+ end
+ end
+ end
+
+ def access_token
+ access_token = Rails.cache.read("baidu_tongji_auth/access_token")
+ if access_token.blank? && refresh_token.present?
+ refresh_access_token
+ access_token = Rails.cache.read("baidu_tongji_auth/access_token")
+ end
+ access_token
+ end
+
+ def refresh_token
+ refresh_token = Rails.cache.read("baidu_tongji_auth/refresh_token")
+ # 如果刷新token失效,access_token也重置
+ if refresh_token.blank?
+ Rails.cache.delete("baidu_tongji_auth/access_token")
+ end
+ refresh_token
+ end
+
+ # 网站概况(趋势数据)
+ def api_overview
+ start_date = Time.now.beginning_of_week
+ end_date = Time.now
+ start_date = Time.now - 1.days if start_date.strftime("%Y%m%d") == end_date.strftime("%Y%m%d")
+ api("overview/getTimeTrendRpt", start_date, end_date, "pv_count,visitor_count,ip_count")
+ end
+
+ # 网站概况(来源网站、搜索词、入口页面、受访页面)
+ def api_overview_getCommonTrackRpt
+ start_date = Time.now.beginning_of_week
+ end_date = Time.now
+ api("overview/getCommonTrackRpt", start_date, end_date, "pv_count")
+ end
+
+ # 全部来源
+ def source_from
+ start_date = Time.now.beginning_of_week
+ end_date = Time.now
+ api("source/all/a", start_date, end_date, "pv_count,visitor_count,ip_count")
+ end
+
+ def api(api_method, start_date, end_date, metrics = nil)
+ start_date_fmt = start_date.strftime("%Y%m%d")
+ end_date_fmt = end_date.strftime("%Y%m%d")
+ api_url = "https://openapi.baidu.com/rest/2.0/tongji/report/getData?access_token=#{access_token}&site_id=#{site_id}&method=#{api_method}&start_date=#{start_date_fmt}&end_date=#{end_date_fmt}&metrics=#{metrics}"
+ data = url_http_post(api_url, {})
+ data['result']
+ end
+
+ def url_http_post(api_url, params)
+ Rails.logger.info "api_url==#{api_url}"
+ uri = URI.parse(api_url)
+ http = Net::HTTP.new uri.host, uri.port
+ http.open_timeout = 60
+ http.read_timeout = 60
+ if uri.scheme == 'https'
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
+ http.use_ssl = true
+ end
+ begin
+ request = Net::HTTP::Post.new(uri)
+ request.set_form_data(params) if params.present?
+ request['Content-Type'] = 'application/json;charset=utf-8'
+ # request['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8'
+ response = http.start { |http| http.request(request) }
+ Rails.logger.info "api response.body==#{response.body}"
+ JSON.parse response.body
+ rescue => err
+ Rails.logger.error("#############api_url:#{api_url},error:#{err.message.size}")
+ # Rails.logger.error("#############api_url:#{api_url},error:#{err.message}")
+ return {}
+ end
+ end
+ end
+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/services/getway/cms/get_service.rb b/app/services/getway/cms/get_service.rb
index 6b7050e84..76c5f27e8 100644
--- a/app/services/getway/cms/get_service.rb
+++ b/app/services/getway/cms/get_service.rb
@@ -16,6 +16,6 @@ class Getway::Cms::GetService < Getway::ClientService
end
def url
- "/cms/doc/open/#{doc_id}".freeze
+ "/cms/doc/open/baseInfo/#{doc_id}".freeze
end
end
\ No newline at end of file
diff --git a/app/services/gitea/user/generate_token_service.rb b/app/services/gitea/user/generate_token_service.rb
index 946bd68ce..e2dd6b0f4 100644
--- a/app/services/gitea/user/generate_token_service.rb
+++ b/app/services/gitea/user/generate_token_service.rb
@@ -29,7 +29,7 @@ class Gitea::User::GenerateTokenService < Gitea::ClientService
end
def request_params
- { name: "#{@username}-#{token_name}" }
+ { name: "#{@username}-#{token_name}", scopes: ["all"] }
end
def token_name
diff --git a/app/services/page_service.rb b/app/services/page_service.rb
index 687added1..5c166e82c 100644
--- a/app/services/page_service.rb
+++ b/app/services/page_service.rb
@@ -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
diff --git a/app/services/projects/create_service.rb b/app/services/projects/create_service.rb
index c4f892f7f..e91f01d7d 100644
--- a/app/services/projects/create_service.rb
+++ b/app/services/projects/create_service.rb
@@ -65,7 +65,8 @@ class Projects::CreateService < ApplicationService
{
hidden: !repo_is_public,
user_id: params[:user_id],
- identifier: params[:repository_name]
+ identifier: params[:repository_name],
+ auto_init: params[:auto_init]
}
end
diff --git a/app/services/repositories/create_service.rb b/app/services/repositories/create_service.rb
index e7ff8bd1d..9fba6122e 100644
--- a/app/services/repositories/create_service.rb
+++ b/app/services/repositories/create_service.rb
@@ -67,7 +67,7 @@ class Repositories::CreateService < ApplicationService
end
def repository_params
- params.merge(project_id: project.id)
+ params.merge(project_id: project.id).except(:auto_init)
end
def gitea_repository_params
@@ -75,7 +75,7 @@ class Repositories::CreateService < ApplicationService
name: params[:identifier],
private: params[:hidden],
# readme: "ReadMe",
- "auto_init": true,
+ auto_init: params[:auto_init],
# "description": "string",
# "gitignores": "string",
# "issue_labels": "string",
@@ -89,7 +89,7 @@ class Repositories::CreateService < ApplicationService
license = project.license
hash = hash.merge(license: license.name) if license
hash = hash.merge(gitignores: ignore.name) if ignore
- hash = hash.merge(auto_init: true) if ignore || license
+ hash = hash.merge(auto_init: true) if ignore && license
hash
end
end
diff --git a/app/views/admins/carousels/index.html.erb b/app/views/admins/carousels/index.html.erb
index 299d1dcfd..e9529c862 100644
--- a/app/views/admins/carousels/index.html.erb
+++ b/app/views/admins/carousels/index.html.erb
@@ -1,6 +1,6 @@
<%
define_admin_breadcrumbs do
- add_admin_breadcrumb('云上实验室', admins_laboratories_path)
+ add_admin_breadcrumb('导航栏配置', admins_laboratories_path)
add_admin_breadcrumb('轮播图')
end
%>
diff --git a/app/views/admins/dashboards/_baidu_tongji.html.erb b/app/views/admins/dashboards/_baidu_tongji.html.erb
new file mode 100644
index 000000000..75fd1cde3
--- /dev/null
+++ b/app/views/admins/dashboards/_baidu_tongji.html.erb
@@ -0,0 +1,68 @@
+
+ 数据来源百度统计,本周 [<%= @current_week_statistic.first&.date %> / <%= @current_week_statistic.last&.date %>]
+
+
+
+
+ 日期 |
+ 访问量 |
+ 访客数 |
+ IP数 |
+ 直接访问占比 |
+ 外部链接占比 |
+ 搜索引擎占比 |
+ 自定义 |
+
+
+
+ <% if @current_week_statistic.size ==1 && @pre_week_statistic.present? %>
+
+ 上周合计 |
+ <%= @pre_week_statistic.map(&:pv).sum %> |
+ <%= @pre_week_statistic.map(&:visitor).sum %> |
+ <%= @pre_week_statistic.map(&:ip).sum %> |
+ <%= (@pre_week_statistic.map(&:source_through).sum.to_f / 7).round(2) %>% |
+ <%= (@pre_week_statistic.map(&:source_link).sum.to_f / 7).round(2) %>% |
+ <%= (@pre_week_statistic.map(&:source_search).sum.to_f / 7).round(2) %>% |
+ <%= ((@pre_week_statistic.map(&:source_custom) - [nil]).sum.to_f / 7).round(2) %>% |
+
+
+ <% end %>
+ <% @current_week_statistic.each_with_index do |week, index| %>
+
+ <%= week.date %> |
+ <%= week.pv %> |
+ <%= week.visitor %> |
+ <%= week.ip %> |
+ <%= week.source_through %>% |
+ <%= week.source_link %>% |
+ <%= week.source_search %>% |
+ <%= week.source_custom.to_f %>% |
+
+
+ <% end %>
+
+ <% current_week_size = @current_week_statistic.size %>
+ 本周合计 |
+ <%= @current_week_statistic.map(&:pv).sum %> |
+ <%= @current_week_statistic.map(&:visitor).sum %> |
+ <%= @current_week_statistic.map(&:ip).sum %> |
+ <%= (@current_week_statistic.map(&:source_through).sum.to_f / current_week_size).round(2) %>% |
+ <%= (@current_week_statistic.map(&:source_link).sum.to_f / current_week_size).round(2) %>% |
+ <%= (@current_week_statistic.map(&:source_search).sum.to_f / current_week_size).round(2) %>% |
+ <%= ((@current_week_statistic.map(&:source_custom) - [nil]).sum.to_f / current_week_size).round(2) %>% |
+
+
+
+
+
+
+<% unless @access_token.present? && @overview_data.present? %>
+
+
+<% end %>
\ No newline at end of file
diff --git a/app/views/admins/dashboards/_baidu_tongji_api.html.erb b/app/views/admins/dashboards/_baidu_tongji_api.html.erb
new file mode 100644
index 000000000..3a18dc405
--- /dev/null
+++ b/app/views/admins/dashboards/_baidu_tongji_api.html.erb
@@ -0,0 +1,67 @@
+<% if @access_token.present? && @overview_data.present? %>
+
+ 数据来源百度统计,本周 <%= @overview_data['timeSpan'] %>
+
+
+
+
+ 日期 |
+ 访问量 |
+ 访客数 |
+ IP数 |
+
+
+
+ <% pv_count = [] %>
+ <% visitor_count = [] %>
+ <% ip_count = [] %>
+ <% @overview_data['items'][0].each_with_index do |date, index| %>
+ <% pv = @overview_data['items'][1][index][0] %>
+ <% visitor = @overview_data['items'][1][index][1] %>
+ <% ip = @overview_data['items'][1][index][2] %>
+
+ <%= date[0] %> |
+ <%= pv %> |
+ <%= visitor %> |
+ <%= ip %> |
+
+
+ <% pv_count.push(pv) %>
+ <% visitor_count.push(visitor) %>
+ <% ip_count.push(ip) %>
+ <% end %>
+
+ 合计 |
+ <%= pv_count %> |
+ <%= visitor_count %> |
+ <%= ip_count %> |
+
+
+
+
+
+
+
+ 直接访问占比 |
+ 外部链接占比 |
+ 搜索引擎占比 |
+ 自定义 |
+
+
+
+
+ <% @source_from_data['items'][1].each_with_index do |source, index| %>
+ <%= ((source[0].to_f / @source_from_data['sum'][0][0].to_f) * 100).round(2).to_s %>% |
+ <% end %>
+
+
+
+<% else %>
+
+
+<% end %>
\ No newline at end of file
diff --git a/app/views/admins/dashboards/index.html.erb b/app/views/admins/dashboards/index.html.erb
index 2d86b4b6c..5441a1802 100644
--- a/app/views/admins/dashboards/index.html.erb
+++ b/app/views/admins/dashboards/index.html.erb
@@ -2,6 +2,38 @@
<% add_admin_breadcrumb('概览', admins_path) %>
<% end %>
+<% cache "/admin/dashboards/#{Time.now.strftime('%Y-%m-%d')}", :expires_in => 1.days do %>
+
+<%end %>
+
+ <%= render partial: 'admins/dashboards/baidu_tongji' %>
\ No newline at end of file
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 } %>