组织首页改版,增加精选、新闻

This commit is contained in:
xxq250 2023-04-10 15:09:41 +08:00
parent f5ec783175
commit 5eff025f62
10 changed files with 166 additions and 16 deletions

View File

@ -0,0 +1,56 @@
class Organizations::IsPinnedProjectsController < Organizations::BaseController
before_action :load_organization
def index
@is_pinned_projects = @organization.pinned_projects.order(position: :desc, created_at: :asc).includes(project: [:project_category, :project_language, :repository]).order(position: :desc)
@is_pinned_projects = kaminari_paginate(@is_pinned_projects)
end
def pin
project_ids = params[:is_pinned_project_ids] || []
@organization.is_pinned_project_ids = project_ids
render_ok
rescue ActiveRecord::RecordNotFound => e
render_not_found
rescue Exception => e
uid_logger_error(e.message)
tip_exception(e.message)
end
def update
@pinned_project = PinnedProject.find_by_id(params[:id])
@pinned_project.attributes = pinned_project_params
if @pinned_project.save
render_ok
else
render_error
end
rescue Exception => e
uid_logger_error(e.message)
tip_exception(e.message)
end
private
def load_organization
@organization = Organization.find_by(login: params[:organization_id]) || Organization.find_by(id: params[:organization_id])
return render_not_found("组织不存在") if @organization.nil?
return render_forbidden("没有查看组织的权限") if org_limited_condition || org_privacy_condition
end
# def is_pinned_project_ids
# if params[:is_pinned_project_ids].present?
# return params[:is_pinned_project_ids].select { |id| @organization.full_member_projects.visible.pluck(:id).include?(id.to_i) }
# end
# if params[:is_pinned_project_id].present?
# return @organization.is_pinned_project_ids unless @organization.full_member_projects.visible.pluck(:id).include?(params[:is_pinned_project_id].to_i)
# return @organization.is_pinned_project_ids.include?(params[:is_pinned_project_id].to_i) ? @organization.is_pinned_project_ids : @organization.is_pinned_project_ids.push(params[:is_pinned_project_id].to_i)
# end
# end
def pinned_project_params
params.require(:pinned_project).permit(:position)
end
end

View File

@ -1,8 +1,8 @@
class Organizations::OrganizationsController < Organizations::BaseController class Organizations::OrganizationsController < Organizations::BaseController
before_action :require_login, except: [:index, :show, :recommend] before_action :require_login, except: [:index, :show, :recommend, :languages]
before_action :require_profile_completed, only: [:create] # before_action :require_profile_completed, only: [:create]
before_action :convert_image!, only: [:create, :update] before_action :convert_image!, only: [:create, :update]
before_action :load_organization, only: [:show, :update, :destroy] before_action :load_organization, only: [:show, :update, :destroy, :update_news, :update_memo, :update_other, :languages]
before_action :check_user_can_edit_org, only: [:update, :destroy] before_action :check_user_can_edit_org, only: [:update, :destroy]
def index def index
@ -62,6 +62,45 @@ class Organizations::OrganizationsController < Organizations::BaseController
tip_exception(e.message) tip_exception(e.message)
end end
def update_news
@organization.organization_extension.update_attributes!(news_banner_id: params[:news_banner_id],
news_title: params[:news_title],
news_url: params[:news_url],
news_content: params[:news_content])
render_ok
end
def update_memo
@organization.organization_extension.update_attributes!(memo: params[:memo])
render_ok
end
def update_other
@organization.organization_extension.update_attributes!(news_banner_id: params[:news_banner_id],
news_content: params[:news_content],
news_title: params[:news_title],
news_url: params[:news_url],
memo: params[:memo])
render_ok
end
def languages
projects = @organization.projects
projects_count = @organization.projects.count
languages_hash = Rails.cache.fetch("query/organizations/languages/#{@organization.id}", :expires_in => 1.days) do
total_languages(projects)
end
languages_hash = languages_hash.sort { |x, y| y[1] <=> x[1] }
sort_hash = Hash[*languages_hash.flatten]
# Rails.logger.info "languages_hash=============#{sort_hash}"
sort_hash= sort_hash.transform_values { |v|
ActionController::Base.helpers.number_to_percentage((v / projects_count), precision: 1)
}.select { |k, v| v != "0.0%" }
render json: sort_hash
end
def destroy def destroy
tip_exception("密码不正确") unless current_user.check_password?(password) tip_exception("密码不正确") unless current_user.check_password?(password)
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
@ -145,4 +184,27 @@ class Organizations::OrganizationsController < Organizations::BaseController
project.project_category.decrement!(:private_projects_count, 1) if project.project_category.present? project.project_category.decrement!(:private_projects_count, 1) if project.project_category.present?
end end
def total_languages(projects)
languages_hash ={}
projects.each do |p|
result = Gitea::Repository::Languages::ListService.call(p.owner.login,
p.identifier, current_user&.gitea_token)
next unless result[:status] === :success
total_byte_size = result[:body].values.sum
hash = result[:body].transform_values { |v|
(v * 100.0 / total_byte_size).to_f
}
hash.each do |key,value|
# Rails.logger.info "key=============#{key}:#{value}"
if languages_hash.has_key?(key)
languages_hash[key] = languages_hash[key] + value
else
languages_hash[key] = value
end
end
end
languages_hash
end
end end

View File

@ -39,15 +39,18 @@
# business :boolean default("0") # business :boolean default("0")
# profile_completed :boolean default("0") # profile_completed :boolean default("0")
# laboratory_id :integer # laboratory_id :integer
# is_shixun_marker :boolean default("0") # platform :string(255) default("0")
# admin_visitable :boolean default("0") # gitea_token :string(255)
# collaborator :boolean default("0")
# gitea_uid :integer # gitea_uid :integer
# is_shixun_marker :boolean default("0")
# is_sync_pwd :boolean default("1") # is_sync_pwd :boolean default("1")
# watchers_count :integer default("0") # watchers_count :integer default("0")
# devops_step :integer default("0") # devops_step :integer default("0")
# gitea_token :string(255) # sponsor_certification :integer default("0")
# platform :string(255) # sponsor_num :integer default("0")
# sponsored_num :integer default("0")
# sponsor_description :text(65535)
# award_time :datetime
# #
# Indexes # Indexes
# #
@ -55,9 +58,8 @@
# index_users_on_homepage_engineer (homepage_engineer) # index_users_on_homepage_engineer (homepage_engineer)
# index_users_on_homepage_teacher (homepage_teacher) # index_users_on_homepage_teacher (homepage_teacher)
# index_users_on_laboratory_id (laboratory_id) # index_users_on_laboratory_id (laboratory_id)
# index_users_on_login (login) UNIQUE # index_users_on_login (login)
# index_users_on_mail (mail) UNIQUE # index_users_on_mail (mail)
# index_users_on_phone (phone) UNIQUE
# index_users_on_type (type) # index_users_on_type (type)
# #
@ -71,13 +73,15 @@ class Organization < Owner
has_many :teams, dependent: :destroy has_many :teams, dependent: :destroy
has_many :organization_users, dependent: :destroy has_many :organization_users, dependent: :destroy
has_many :team_users, dependent: :destroy has_many :team_users, dependent: :destroy
has_many :pinned_projects, class_name: 'PinnedProject', foreign_key: :user_id, dependent: :destroy
has_many :is_pinned_projects, through: :pinned_projects, source: :project, validate: false
validates :login, presence: true validates :login, presence: true
validates_uniqueness_of :login, :if => Proc.new { |user| user.login_changed? && user.login.present? }, case_sensitive: false 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: "只能含有数字、字母、下划线且不能以下划线开头和结尾" }
delegate :description, :website, :location, :repo_admin_change_team_access, :recommend, delegate :description, :website, :location, :repo_admin_change_team_access, :recommend,
:visibility, :max_repo_creation, :num_projects, :num_users, :num_teams, to: :organization_extension, allow_nil: true :visibility, :max_repo_creation, :num_projects, :num_users, :num_teams, :news_banner_id, :news_content, :memo, to: :organization_extension, allow_nil: true
scope :with_visibility, ->(visibility) { joins(:organization_extension).where(organization_extensions: {visibility: visibility}) if visibility.present? } scope :with_visibility, ->(visibility) { joins(:organization_extension).where(organization_extensions: {visibility: visibility}) if visibility.present? }

View File

@ -16,6 +16,9 @@
# num_users :integer default("0") # num_users :integer default("0")
# num_teams :integer default("0") # num_teams :integer default("0")
# recommend :boolean default("0") # recommend :boolean default("0")
# news_banner_id :integer
# news_content :text(65535)
# memo :text(65535)
# #
# Indexes # Indexes
# #

View File

@ -67,6 +67,7 @@ class Owner < ApplicationRecord
has_many :projects, foreign_key: :user_id, dependent: :destroy has_many :projects, foreign_key: :user_id, dependent: :destroy
has_many :repositories, foreign_key: :user_id, dependent: :destroy has_many :repositories, foreign_key: :user_id, dependent: :destroy
has_many :applied_transfer_projects, dependent: :destroy has_many :applied_transfer_projects, dependent: :destroy
has_many :pinned_projects, foreign_key: :user_id, dependent: :destroy
scope :like, lambda { |keywords| scope :like, lambda { |keywords|
# 表情处理 # 表情处理

View File

@ -17,6 +17,7 @@
class PinnedProject < ApplicationRecord class PinnedProject < ApplicationRecord
belongs_to :user # belongs_to :user
belongs_to :owner, class_name: 'Owner', foreign_key: :user_id, optional: true
belongs_to :project belongs_to :project
end end

View File

@ -3,7 +3,7 @@
# Table name: projects # Table name: projects
# #
# id :integer not null, primary key # id :integer not null, primary key
# name :string(255) default(""), not null # name :string(255)
# description :text(4294967295) # description :text(4294967295)
# homepage :string(255) default("") # homepage :string(255) default("")
# is_public :boolean default("1"), not null # is_public :boolean default("1"), not null
@ -122,7 +122,7 @@ class Project < ApplicationRecord
has_many :project_units, dependent: :destroy has_many :project_units, dependent: :destroy
has_one :applied_transfer_project,-> { order created_at: :desc }, dependent: :destroy has_one :applied_transfer_project,-> { order created_at: :desc }, dependent: :destroy
has_many :pinned_projects, dependent: :destroy has_many :pinned_projects, dependent: :destroy
has_many :has_pinned_users, through: :pinned_projects, source: :user has_many :has_pinned_users, through: :pinned_projects, source: :owner
has_many :webhooks, class_name: "Gitea::Webhook", primary_key: :gpid, foreign_key: :repo_id has_many :webhooks, class_name: "Gitea::Webhook", primary_key: :gpid, foreign_key: :repo_id
has_many :user_trace_tasks, dependent: :destroy has_many :user_trace_tasks, dependent: :destroy
has_many :project_invite_links, dependent: :destroy has_many :project_invite_links, dependent: :destroy

View File

@ -12,3 +12,8 @@ json.num_users organization.num_users
json.num_teams organization.num_teams json.num_teams organization.num_teams
json.avatar_url url_to_avatar(organization) json.avatar_url url_to_avatar(organization)
json.created_at organization.created_on.strftime("%Y-%m-%d") json.created_at organization.created_on.strftime("%Y-%m-%d")
json.news_banner_id organization.news_banner_id
json.news_content organization.news_content
json.memo organization.memo
json.news_title organization.news_title
json.news_url organization.news_url

View File

@ -168,6 +168,17 @@ Rails.application.routes.draw do
end end
end end
get :recommend, on: :collection get :recommend, on: :collection
resources :is_pinned_projects, only: [:index, :update] do
collection do
post :pin
end
end
member do
post :update_news
post :update_memo
post :update_other
get :languages
end
end end
end end

View File

@ -0,0 +1,7 @@
class AddOrganizationExtensionsNews < ActiveRecord::Migration[5.2]
def change
add_column :organization_extensions, :news_banner_id, :integer
add_column :organization_extensions, :news_content, :text
add_column :organization_extensions, :memo, :text
end
end