| @@ -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 | |||
| @@ -1,8 +1,8 @@ | |||
| class Organizations::OrganizationsController < Organizations::BaseController | |||
| before_action :require_login, except: [:index, :show, :recommend] | |||
| before_action :require_profile_completed, only: [:create] | |||
| before_action :require_login, except: [:index, :show, :recommend, :languages] | |||
| # before_action :require_profile_completed, only: [:create] | |||
| 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] | |||
| def index | |||
| @@ -62,6 +62,45 @@ class Organizations::OrganizationsController < Organizations::BaseController | |||
| tip_exception(e.message) | |||
| 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 | |||
| tip_exception("密码不正确") unless current_user.check_password?(password) | |||
| ActiveRecord::Base.transaction do | |||
| @@ -144,5 +183,28 @@ class Organizations::OrganizationsController < Organizations::BaseController | |||
| # 更新对应所属分类下的项目数量(私有) | |||
| project.project_category.decrement!(:private_projects_count, 1) if project.project_category.present? | |||
| 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 | |||
| @@ -39,15 +39,18 @@ | |||
| # business :boolean default("0") | |||
| # profile_completed :boolean default("0") | |||
| # laboratory_id :integer | |||
| # is_shixun_marker :boolean default("0") | |||
| # admin_visitable :boolean default("0") | |||
| # collaborator :boolean default("0") | |||
| # platform :string(255) default("0") | |||
| # gitea_token :string(255) | |||
| # gitea_uid :integer | |||
| # is_shixun_marker :boolean default("0") | |||
| # is_sync_pwd :boolean default("1") | |||
| # watchers_count :integer default("0") | |||
| # devops_step :integer default("0") | |||
| # gitea_token :string(255) | |||
| # platform :string(255) | |||
| # sponsor_certification :integer default("0") | |||
| # sponsor_num :integer default("0") | |||
| # sponsored_num :integer default("0") | |||
| # sponsor_description :text(65535) | |||
| # award_time :datetime | |||
| # | |||
| # Indexes | |||
| # | |||
| @@ -55,9 +58,8 @@ | |||
| # index_users_on_homepage_engineer (homepage_engineer) | |||
| # index_users_on_homepage_teacher (homepage_teacher) | |||
| # index_users_on_laboratory_id (laboratory_id) | |||
| # index_users_on_login (login) UNIQUE | |||
| # index_users_on_mail (mail) UNIQUE | |||
| # index_users_on_phone (phone) UNIQUE | |||
| # index_users_on_login (login) | |||
| # index_users_on_mail (mail) | |||
| # index_users_on_type (type) | |||
| # | |||
| @@ -71,13 +73,15 @@ class Organization < Owner | |||
| has_many :teams, dependent: :destroy | |||
| has_many :organization_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_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: "只能含有数字、字母、下划线且不能以下划线开头和结尾" } | |||
| 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? } | |||
| @@ -16,6 +16,9 @@ | |||
| # num_users :integer default("0") | |||
| # num_teams :integer default("0") | |||
| # recommend :boolean default("0") | |||
| # news_banner_id :integer | |||
| # news_content :text(65535) | |||
| # memo :text(65535) | |||
| # | |||
| # Indexes | |||
| # | |||
| @@ -67,6 +67,7 @@ class Owner < ApplicationRecord | |||
| has_many :projects, foreign_key: :user_id, dependent: :destroy | |||
| has_many :repositories, foreign_key: :user_id, dependent: :destroy | |||
| has_many :applied_transfer_projects, dependent: :destroy | |||
| has_many :pinned_projects, foreign_key: :user_id, dependent: :destroy | |||
| scope :like, lambda { |keywords| | |||
| # 表情处理 | |||
| @@ -17,6 +17,7 @@ | |||
| class PinnedProject < ApplicationRecord | |||
| belongs_to :user | |||
| # belongs_to :user | |||
| belongs_to :owner, class_name: 'Owner', foreign_key: :user_id, optional: true | |||
| belongs_to :project | |||
| end | |||
| @@ -3,7 +3,7 @@ | |||
| # Table name: projects | |||
| # | |||
| # id :integer not null, primary key | |||
| # name :string(255) default(""), not null | |||
| # name :string(255) | |||
| # description :text(4294967295) | |||
| # homepage :string(255) default("") | |||
| # is_public :boolean default("1"), not null | |||
| @@ -122,7 +122,7 @@ class Project < ApplicationRecord | |||
| has_many :project_units, dependent: :destroy | |||
| has_one :applied_transfer_project,-> { order created_at: :desc }, 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 :user_trace_tasks, dependent: :destroy | |||
| has_many :project_invite_links, dependent: :destroy | |||
| @@ -11,4 +11,9 @@ json.num_projects organization.num_projects | |||
| json.num_users organization.num_users | |||
| json.num_teams organization.num_teams | |||
| 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 | |||
| @@ -168,6 +168,17 @@ Rails.application.routes.draw do | |||
| end | |||
| end | |||
| 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 | |||
| @@ -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 | |||