mirror of
https://gitlink.org.cn/Gitlink/forgeplus.git
synced 2026-05-17 18:25:56 +08:00
FIX * ENHANCEMENTS
* ADD 用户活动统计图表功能 * ADD 用户精选项目功能 * ADD 用户贡献度统计图表功能 * ADD 用户开发能力数据统计工 * ADD 用户角色定位展示功能 * ADD 用户专业定位标签展示功能 * ADD 修改用户基本资料功能 * ADD 更改密码功能 * ADD 用户个人主页基本现在展示可配置功能 * BUGFIXES * Fix 解决一些bug * Fix 优化美化页面change license
This commit is contained in:
@@ -203,6 +203,25 @@ class AccountsController < ApplicationController
|
||||
# session[:user_id] = @user.id
|
||||
end
|
||||
|
||||
def change_password
|
||||
@user = User.find_by(login: params[:login])
|
||||
return render_error("未找到相关用户!") if @user.blank?
|
||||
return render_error("旧密码不正确") unless @user.check_password?(params[:old_password])
|
||||
|
||||
sync_params = {
|
||||
password: params[:password].to_s,
|
||||
email: @user.mail
|
||||
}
|
||||
|
||||
interactor = Gitea::User::UpdateInteractor.call(@user.login, sync_params)
|
||||
if interactor.success?
|
||||
@user.update_attribute(:password, params[:password])
|
||||
render_ok
|
||||
else
|
||||
render_error(interactor.error)
|
||||
end
|
||||
end
|
||||
|
||||
# 忘记密码
|
||||
def reset_password
|
||||
begin
|
||||
|
||||
@@ -32,7 +32,7 @@ class Admins::AuthSchoolsController < Admins::BaseController
|
||||
def search_manager
|
||||
school = School.find_by(id: params[:school_id])
|
||||
user_ids = school&.ec_school_users&.pluck(:user_id)
|
||||
@users = User.where.not(id: user_ids).where("concat(lastname, firstname) like ?", "%#{params[:name].strip.to_s}%").limit(10)
|
||||
@users = User.where.not(id: user_ids).where("CONCAT_WS(lastname, firstname, nickname) like ?", "%#{params[:name].strip.to_s}%").limit(10)
|
||||
end
|
||||
|
||||
# 添加认证学校管理员
|
||||
|
||||
@@ -32,7 +32,7 @@ class Admins::LaboratoriesController < Admins::BaseController
|
||||
|
||||
keyword = params[:keyword].to_s.strip
|
||||
if keyword.present?
|
||||
like_sql = 'shixuns.name LIKE :keyword OR CONCAT(users.lastname, users.firstname) LIKE :keyword '\
|
||||
like_sql = 'shixuns.name LIKE :keyword OR CONCAT_WS(users.lastname, users.firstname, users.nickname) LIKE :keyword '\
|
||||
'OR mirror_repositories.name LIKE :keyword'
|
||||
shixuns = shixuns.joins(:user, :mirror_repositories).where(like_sql, keyword: "%#{keyword}%")
|
||||
end
|
||||
@@ -48,7 +48,7 @@ class Admins::LaboratoriesController < Admins::BaseController
|
||||
|
||||
keyword = params[:keyword].to_s.strip
|
||||
if keyword.present?
|
||||
like_sql = 'subjects.name LIKE :keyword OR CONCAT(users.lastname, users.firstname) LIKE :keyword'
|
||||
like_sql = 'subjects.name LIKE :keyword OR CONCAT_WS(users.lastname, users.firstname, users.nickname) LIKE :keyword'
|
||||
subjects = subjects.joins(:user).where(like_sql, keyword: "%#{keyword}%")
|
||||
end
|
||||
|
||||
|
||||
@@ -773,7 +773,26 @@ class ApplicationController < ActionController::Base
|
||||
def base_url
|
||||
request.base_url
|
||||
end
|
||||
|
||||
def convert_image!
|
||||
@image = params[:image] || user_params[:image]
|
||||
return unless @image.present?
|
||||
max_size = EduSetting.get('upload_avatar_max_size') || 2 * 1024 * 1024 # 2M
|
||||
if @image.class == ActionDispatch::Http::UploadedFile
|
||||
render_error('请上传文件') if @image.size.zero?
|
||||
render_error('文件大小超过限制') if @image.size > max_size.to_i
|
||||
else
|
||||
image = @image.to_s.strip
|
||||
return render_error('请上传正确的图片') if image.blank?
|
||||
@image = Util.convert_base64_image(image, max_size: max_size.to_i)
|
||||
end
|
||||
rescue Base64ImageConverter::Error => ex
|
||||
render_error(ex.message)
|
||||
end
|
||||
|
||||
def avatar_path(object)
|
||||
ApplicationController.helpers.disk_filename(object.class, object.id)
|
||||
end
|
||||
|
||||
private
|
||||
def object_not_found
|
||||
|
||||
@@ -18,7 +18,7 @@ class MembersController < ApplicationController
|
||||
scope = @project.members.includes(:roles, user: :user_extension)
|
||||
search = params[:search].to_s.downcase
|
||||
role = params[:role].to_s
|
||||
scope = scope.joins(:user).where("LOWER(concat(users.lastname, users.firstname, users.login, users.mail)) LIKE ?", "%#{search.split(" ").join('|')}%") if search.present?
|
||||
scope = scope.joins(:user).where("LOWER(CONCAT_WS(users.lastname, users.firstname, users.login, users.mail, users.nickname)) LIKE ?", "%#{search.split(" ").join('|')}%") if search.present?
|
||||
scope = scope.joins(:roles).where("roles.name LIKE ?", "%#{role}%") if role.present?
|
||||
|
||||
@total_count = scope.size
|
||||
|
||||
@@ -5,7 +5,7 @@ class Organizations::OrganizationUsersController < Organizations::BaseController
|
||||
def index
|
||||
@organization_users = @organization.organization_users.includes(:user)
|
||||
search = params[:search].to_s.downcase
|
||||
@organization_users = @organization_users.joins(:user).where("LOWER(CONCAT_WS(users.lastname, users.firstname, users.login, users.mail)) LIKE ?", "%#{search.split(" ").join('|')}%") if search.present?
|
||||
@organization_users = @organization_users.joins(:user).where("LOWER(CONCAT_WS(users.lastname, users.firstname, users.login, users.mail, users.nickname)) LIKE ?", "%#{search.split(" ").join('|')}%") if search.present?
|
||||
|
||||
@organization_users = kaminari_paginate(@organization_users)
|
||||
end
|
||||
|
||||
@@ -70,25 +70,6 @@ class Organizations::OrganizationsController < Organizations::BaseController
|
||||
end
|
||||
|
||||
private
|
||||
def convert_image!
|
||||
return unless params[:image].present?
|
||||
max_size = EduSetting.get('upload_avatar_max_size') || 2 * 1024 * 1024 # 2M
|
||||
if params[:image].class == ActionDispatch::Http::UploadedFile
|
||||
@image = params[:image]
|
||||
render_error('请上传文件') if @image.size.zero?
|
||||
render_error('文件大小超过限制') if @image.size > max_size.to_i
|
||||
else
|
||||
image = params[:image].to_s.strip
|
||||
return render_error('请上传正确的图片') if image.blank?
|
||||
@image = Util.convert_base64_image(image, max_size: max_size.to_i)
|
||||
end
|
||||
rescue Base64ImageConverter::Error => ex
|
||||
render_error(ex.message)
|
||||
end
|
||||
|
||||
def avatar_path(organization)
|
||||
ApplicationController.helpers.disk_filename(organization.class, organization.id)
|
||||
end
|
||||
|
||||
def organization_params
|
||||
params.permit(:name, :description, :website, :location,
|
||||
|
||||
@@ -177,7 +177,7 @@ class ProjectsController < ApplicationController
|
||||
end
|
||||
|
||||
def recommend
|
||||
@projects = Project.recommend.includes(:repository, :project_category, :owner).order(id: :desc)
|
||||
@projects = Project.recommend.includes(:repository, :project_category, :owner).order(visits: :desc)
|
||||
end
|
||||
|
||||
def about
|
||||
|
||||
26
app/controllers/users/headmaps_controller.rb
Normal file
26
app/controllers/users/headmaps_controller.rb
Normal file
@@ -0,0 +1,26 @@
|
||||
class Users::HeadmapsController < Users::BaseController
|
||||
def index
|
||||
result = Gitea::User::HeadmapService.call(observed_user.login, start_stamp, end_stamp)
|
||||
@headmaps = result[2]
|
||||
rescue Exception => e
|
||||
uid_logger_error(e.message)
|
||||
tip_exception(e.message)
|
||||
end
|
||||
|
||||
private
|
||||
def start_stamp
|
||||
if params[:year].present?
|
||||
Date.new(params[:year], 1).to_time.to_i
|
||||
else
|
||||
Date.today.to_time.to_i - 365*24*60*60
|
||||
end
|
||||
end
|
||||
|
||||
def end_stamp
|
||||
if params[:year].present?
|
||||
Date.new(params[:year], 1).to_time.to_i + 365*24*60*60
|
||||
else
|
||||
Date.today.to_time.to_i
|
||||
end
|
||||
end
|
||||
end
|
||||
45
app/controllers/users/is_pinned_projects_controller.rb
Normal file
45
app/controllers/users/is_pinned_projects_controller.rb
Normal file
@@ -0,0 +1,45 @@
|
||||
class Users::IsPinnedProjectsController < Users::BaseController
|
||||
before_action :private_user_resources!, only: [:pin]
|
||||
def index
|
||||
@is_pinned_projects = observed_user.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
|
||||
observed_user.is_pinned_project_ids = is_pinned_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 is_pinned_project_ids
|
||||
if params[:is_pinned_project_ids].present?
|
||||
return params[:is_pinned_project_ids].select{|id| observed_user.full_member_projects.visible.pluck(:id).include?(id.to_i) }
|
||||
end
|
||||
if params[:is_pinned_project_id].present?
|
||||
return observed_user.is_pinned_project_ids unless observed_user.full_member_projects.visible.pluck(:id).include?(params[:is_pinned_project_id].to_i)
|
||||
return observed_user.is_pinned_project_ids.include?(params[:is_pinned_project_id].to_i) ? observed_user.is_pinned_project_ids : observed_user.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
|
||||
11
app/controllers/users/project_trends_controller.rb
Normal file
11
app/controllers/users/project_trends_controller.rb
Normal file
@@ -0,0 +1,11 @@
|
||||
class Users::ProjectTrendsController < Users::BaseController
|
||||
|
||||
def index
|
||||
if params[:date].present?
|
||||
@project_trends = observed_user.project_trends.where("DATE(created_at) = ?", params[:date])
|
||||
else
|
||||
@project_trends = observed_user.project_trends
|
||||
end
|
||||
@project_trends = kaminari_paginate(@project_trends.includes(:trend, :project).order(created_at: :desc))
|
||||
end
|
||||
end
|
||||
217
app/controllers/users/statistics_controller.rb
Normal file
217
app/controllers/users/statistics_controller.rb
Normal file
@@ -0,0 +1,217 @@
|
||||
class Users::StatisticsController < Users::BaseController
|
||||
before_action :preload_develop_data, only: [:develop]
|
||||
|
||||
# 近期活动统计
|
||||
def activity
|
||||
date_range = (1.week.ago.to_date..Date.today).to_a
|
||||
commit_request = Gitea::User::HeadmapService.call(observed_user.login, 1.week.ago.to_date.to_time.to_i, Date.today.to_time.to_i)
|
||||
commit_data = commit_request[2]
|
||||
@date_data = []
|
||||
@issue_data = []
|
||||
@pull_request_data = []
|
||||
@commit_data = []
|
||||
date_range.each do |date|
|
||||
@date_data << date.strftime("%Y.%m.%d")
|
||||
@issue_data << observed_user.issues.where("DATE(created_on) = ?", date).size
|
||||
@pull_request_data << observed_user.pull_requests.where("DATE(created_at) = ?", date).size
|
||||
date_commit_data = commit_data.select{|item| item["timestamp"] == date.to_time.to_i}
|
||||
@commit_data << (date_commit_data.blank? ? 0 : date_commit_data[0]["contributions"].to_i)
|
||||
end
|
||||
render :json => {dates: @date_data, issues_count: @issue_data, pull_requests_count: @pull_request_data, commits_count: @commit_data}
|
||||
end
|
||||
|
||||
# 开发能力
|
||||
def develop
|
||||
if params[:start_time].present? && params[:end_time].present?
|
||||
# 影响力
|
||||
@influence = (60.0 + @follow_count / (@follow_count + 10.0) * 40.0).to_i
|
||||
@platform_influence = (60.0 + @platform_follow_count / (@platform_follow_count + 10.0) * 40.0).to_i
|
||||
# 贡献度
|
||||
@contribution = (60.0 + @pullrequest_count / (@pullrequest_count + 10.0) * 40.0).to_i
|
||||
@platform_contribution = (60.0 + @platform_pullrequest_count / (@platform_pullrequest_count + 10.0) * 40.0).to_i
|
||||
# 活跃度
|
||||
@activity = (60.0 + @issues_count / (@issues_count + 10.0) * 40.0).to_i
|
||||
@platform_activity = (60.0 + @platform_issues_count / (@platform_issues_count + 10.0) * 40.0).to_i
|
||||
# 项目经验
|
||||
@experience = 10 * @project_count + 5 * @fork_count + @project_watchers_count + @project_praises_count
|
||||
@experience = (60.0 + @experience / (@experience + 100.0) * 40.0).to_i
|
||||
@platform_experience = 10 * @platform_project_count + 5 * @platform_fork_count + @platform_project_watchers_count + @platform_project_praises_count
|
||||
@platform_experience = (60.0 + @platform_experience / (@platform_experience + 100.0) * 40.0).to_i
|
||||
# 语言能力
|
||||
@language = (60.0 + @project_languages_count.length / (@project_languages_count.length + 5.0) * 40.0).to_i
|
||||
@platform_language = (60.0 + @platform_project_languages_count.length / (@platform_project_languages_count.length + 5.0) * 40.0).to_i
|
||||
# 语言百分比
|
||||
@languages_percent = Hash.new
|
||||
for key in @project_languages_count.keys do
|
||||
@languages_percent[key] = (@project_languages_count[key].to_f / @project_languages_count.values.sum).round(2)
|
||||
end
|
||||
@platform_languages_percent = Hash.new
|
||||
for key in @platform_project_languages_count.keys do
|
||||
@platform_languages_percent[key] = (@platform_project_languages_count[key].to_f / @platform_project_languages_count.values.sum).round(2)
|
||||
end
|
||||
# 各门语言分数
|
||||
@each_language_score = Hash.new
|
||||
for key in @project_languages_count.keys do
|
||||
@each_language_score[key] = (60.0 + @project_languages_count[key] / (@project_languages_count[key] + 5.0) * 40.0).to_i
|
||||
end
|
||||
@platform_each_language_score = Hash.new
|
||||
for key in @platform_project_languages_count.keys do
|
||||
@platform_each_language_score[key] = (60.0 + @platform_project_languages_count[key] / (@platform_project_languages_count[key] + 5.0) * 40.0).to_i
|
||||
end
|
||||
else
|
||||
# 影响力
|
||||
@influence = (60.0 + @follow_count / (@follow_count + 20.0) * 40.0).to_i
|
||||
@platform_influence = (60.0 + @platform_follow_count / (@platform_follow_count + 20.0) * 40.0).to_i
|
||||
|
||||
# 贡献度
|
||||
@contribution = (60.0 + @pullrequest_count / (@pullrequest_count + 20.0) * 40.0).to_i
|
||||
@platform_contribution = (60.0 + @platform_pullrequest_count / (@platform_pullrequest_count + 20.0) * 40.0).to_i
|
||||
|
||||
# 活跃度
|
||||
@activity = (60.0 + @issues_count / (@issues_count + 80.0) * 40.0).to_i
|
||||
@platform_activity = (60.0 + @platform_issues_count / (@platform_issues_count + 80.0) * 40.0).to_i
|
||||
|
||||
# 项目经验
|
||||
@experience = 10 * @project_count + 5 * @fork_count + @project_watchers_count + @project_praises_count
|
||||
@experience = (60.0 + @experience / (@experience + 100.0) * 40.0).to_i
|
||||
@platform_experience = 10 * @platform_project_count + 5 * @platform_fork_count + @platform_project_watchers_count + @platform_project_praises_count
|
||||
@platform_experience = (60.0 + @platform_experience / (@platform_experience + 100.0) * 40.0).to_i
|
||||
# 语言能力
|
||||
@language = (60.0 + @project_languages_count.length / (@project_languages_count.length + 5.0) * 40.0).to_i
|
||||
@platform_language = (60.0 + @platform_project_languages_count.length / (@platform_project_languages_count.length + 5.0) * 40.0).to_i
|
||||
|
||||
# 语言百分比
|
||||
@languages_percent = Hash.new
|
||||
for key in @project_languages_count.keys do
|
||||
@languages_percent[key] = (@project_languages_count[key].to_f / @project_languages_count.values.sum).round(2)
|
||||
end
|
||||
# @platform_languages_percent = Hash.new
|
||||
# for key in @platform_project_languages_count.keys do
|
||||
# @platform_languages_percent[key] = (@platform_project_languages_count[key].to_f / @platform_project_languages_count.values.sum).round(2)
|
||||
# end
|
||||
# 各门语言分数
|
||||
@each_language_score = Hash.new
|
||||
for key in @project_languages_count.keys do
|
||||
@each_language_score[key] = (60.0 + @project_languages_count[key] / (@project_languages_count[key] + 5.0) * 40.0).to_i
|
||||
end
|
||||
# @platform_each_language_score = Hash.new
|
||||
# for key in @platform_project_languages_count.keys do
|
||||
# @platform_each_language_score[key] = (60.0 + @platform_project_languages_count[key] / (@platform_project_languages_count[key] + 5.0) * 40.0).to_i
|
||||
# end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# 角色定位
|
||||
def role
|
||||
full_member_projects = observed_user.full_member_projects
|
||||
owner_projects = filter_member_projects_by_role("Owner")
|
||||
manager_projects = filter_member_projects_by_role("Manager").where.not(id: owner_projects.ids)
|
||||
developer_projects = filter_member_projects_by_role("Developer").where.not(id: owner_projects.ids + manager_projects.ids)
|
||||
reporter_projects = filter_member_projects_by_role("Reporter").where.not(id: owner_projects.ids + manager_projects.ids + developer_projects.ids)
|
||||
|
||||
@full_member_projects_count = full_member_projects.size
|
||||
@owner_projects_count = owner_projects.size
|
||||
@manager_projects_count = manager_projects.size
|
||||
@developer_projects_count = developer_projects.size
|
||||
@reporter_projects_count = reporter_projects.size
|
||||
|
||||
end
|
||||
|
||||
# 专业定位
|
||||
def major
|
||||
# 参与项目
|
||||
join_normal_projects_sql = Project.members_projects(observed_user.id).to_sql
|
||||
join_org_projects_sql = Project.joins(team_projects: [team: :team_users]).where(team_users: {user_id: observed_user.id}).to_sql
|
||||
# 关注项目
|
||||
star_projects_sql = Project.joins(:watchers).where(watchers: {watchable_type: "Project", user_id: observed_user.id}).to_sql
|
||||
# fork项目
|
||||
fork_projects_sql = Project.where(id: observed_user.fork_users.select(:id, :fork_project_id).pluck(:fork_project_id)).to_sql
|
||||
major_projects = Project.from("( #{ join_normal_projects_sql} UNION #{ join_org_projects_sql } UNION #{ star_projects_sql } UNION #{fork_projects_sql}) AS projects").distinct
|
||||
categories = ProjectCategory.joins(:projects).merge(Project.where(id: time_filter(major_projects, 'created_on'))).distinct.pluck(:name)
|
||||
render :json => {categories: categories}
|
||||
end
|
||||
|
||||
private
|
||||
def time_filter(collection, time_field)
|
||||
if params[:start_time].present? && params[:end_time].present?
|
||||
return collection.where("#{time_field} > ? AND #{time_field} < ?", Time.at(params[:start_time].to_i).beginning_of_day, Time.at(params[:end_time].to_i).end_of_day)
|
||||
else
|
||||
return collection
|
||||
end
|
||||
rescue
|
||||
return collection
|
||||
end
|
||||
|
||||
def filter_member_projects_by_role(role)
|
||||
case role
|
||||
when 'Owner'
|
||||
normal_projects_sql = Project.joins(members: :roles).where(user_id: observed_user.id).where(members: {user_id: observed_user.id}, roles: {name: 'Manager'}).to_sql
|
||||
org_projects_sql = Project.joins(:owner, teams: :team_users).where(users: {type: 'Organization'}, teams: {authorize: "owner"}, team_users: {user_id: observed_user.id}).to_sql
|
||||
when "Manager"
|
||||
normal_projects_sql = Project.joins(members: :roles).where.not(user_id: observed_user.id).where(members: {user_id: observed_user.id}, roles: {name: 'Manager'}).to_sql
|
||||
org_projects_sql = Project.joins(:owner, teams: :team_users).where(users: {type: 'Organization'}, teams: {authorize: "admin"}, team_users: {user_id: observed_user.id}).to_sql
|
||||
when "Developer"
|
||||
normal_projects_sql = Project.joins(members: :roles).where.not(user_id: observed_user.id).where(members: {user_id: observed_user.id}, roles: {name: 'Developer'}).to_sql
|
||||
org_projects_sql = Project.joins(:owner, teams: :team_users).where(users: {type: 'Organization'}, teams: {authorize: "write"}, team_users: {user_id: observed_user.id}).to_sql
|
||||
when "Reporter"
|
||||
normal_projects_sql = Project.joins(members: :roles).where.not(user_id: observed_user.id).where(members: {user_id: observed_user.id}, roles: {name: 'Reporter'}).to_sql
|
||||
org_projects_sql = Project.joins(:owner, teams: :team_users).where(users: {type: 'Organization'}, teams: {authorize: "read"}, team_users: {user_id: observed_user.id}).to_sql
|
||||
end
|
||||
return time_filter(Project.from("( #{normal_projects_sql} UNION #{org_projects_sql} ) AS projects").distinct, 'created_on')
|
||||
end
|
||||
|
||||
def preload_develop_data
|
||||
if params[:start_time].present? && params[:end_time].present?
|
||||
# 用户被follow数量
|
||||
@follow_count = time_filter(Watcher.where(watchable: observed_user), 'created_at').count
|
||||
@platform_follow_count = time_filter(Watcher.where(watchable_type: 'User'), 'created_at').count
|
||||
# 用户pr数量
|
||||
@pullrequest_count = time_filter(PullRequest.where(user_id: observed_user.id), 'created_at').count
|
||||
@platform_pullrequest_count = time_filter(PullRequest, 'created_at').count
|
||||
# 用户issue数量
|
||||
@issues_count = time_filter(Issue.where(author_id: observed_user.id), 'created_on').count
|
||||
@platform_issues_count = time_filter(Issue, 'created_on').count
|
||||
# 用户总项目数
|
||||
@project_count = time_filter(Project.where(user_id:observed_user.id), 'created_on').count
|
||||
@platform_project_count = time_filter(Project, 'created_on').count
|
||||
# 用户项目被fork数量
|
||||
@fork_count = time_filter(Project.where(user_id:observed_user.id), 'created_on').sum("forked_count")
|
||||
@platform_fork_count = time_filter(Project, 'created_on').sum("forked_count")
|
||||
# 用户项目关注数
|
||||
@project_watchers_count = time_filter(Project.where(user_id: observed_user.id), 'created_on').sum("watchers_count")
|
||||
@platform_project_watchers_count = time_filter(Project, 'created_on').sum("watchers_count")
|
||||
# 用户项目点赞数
|
||||
@project_praises_count = time_filter(Project.where(user_id: observed_user.id), 'created_on').sum("praises_count")
|
||||
@platform_project_praises_count = time_filter(Project, 'created_on').sum("praises_count")
|
||||
# 用户不同语言项目数量
|
||||
@project_languages_count = time_filter(Project.where(user_id: observed_user.id), 'created_on').joins(:project_language).group("project_languages.name").count
|
||||
@platform_project_languages_count = time_filter(Project, 'created_on').joins(:project_language).group("project_languages.name").count
|
||||
else
|
||||
# 用户被follow数量
|
||||
@follow_count = Cache::UserFollowCountService.call(observed_user)
|
||||
@platform_follow_count = Cache::PlatformFollowCountService.call
|
||||
# 用户pr数量
|
||||
@pullrequest_count = Cache::UserPullrequestCountService.call(observed_user)
|
||||
@platform_pullrequest_count = Cache::PlatformPullrequestCountService.call
|
||||
# 用户issue数量
|
||||
@issues_count = Cache::UserIssueCountService.call(observed_user)
|
||||
@platform_issues_count = Cache::PlatformIssueCountService.call
|
||||
# 用户总项目数
|
||||
@project_count = Cache::UserProjectCountService.call(observed_user)
|
||||
@platform_project_count = Cache::PlatformProjectCountService.call
|
||||
# 用户项目被fork数量
|
||||
@fork_count = Cache::UserProjectForkCountService.call(observed_user)
|
||||
@platform_fork_count = Cache::PlatformProjectForkCountService.call
|
||||
# 用户项目关注数
|
||||
@project_watchers_count = Cache::UserProjectWatchersCountService.call(observed_user)
|
||||
@platform_project_watchers_count = Cache::PlatformProjectWatchersCountService.call
|
||||
# 用户项目点赞数
|
||||
@project_praises_count = Cache::UserProjectPraisesCountService.call(observed_user)
|
||||
@platform_project_praises_count = Cache::PlatformProjectPraisesCountService.call
|
||||
# 用户不同语言项目数量
|
||||
@project_languages_count = Cache::UserProjectLanguagesCountService.call(observed_user)
|
||||
@platform_project_languages_count = Cache::PlatformProjectLanguagesCountService.call
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -6,6 +6,7 @@ class UsersController < ApplicationController
|
||||
before_action :check_user_exist, only: [:show, :homepage_info,:projects, :watch_users, :fan_users, :hovercard]
|
||||
before_action :require_login, only: %i[me list sync_user_info]
|
||||
before_action :connect_to_ci_db, only: [:get_user_info]
|
||||
before_action :convert_image!, only: [:update]
|
||||
skip_before_action :check_sign, only: [:attachment_show]
|
||||
|
||||
def connect_to_ci_db(options={})
|
||||
@@ -62,7 +63,7 @@ class UsersController < ApplicationController
|
||||
|
||||
def fan_users
|
||||
watchers = @user.watchers.includes(:user).order("watchers.created_at desc")
|
||||
watchers = watchers.joins(:user).where("LOWER(concat(users.lastname, users.firstname, users.login)) LIKE ?", "%#{params[:search].split(" ").join('|')}%") if params[:search].present?
|
||||
watchers = watchers.joins(:user).where("LOWER(CONCAT_WS(users.lastname, users.firstname, users.login, users.nickname)) LIKE ?", "%#{params[:search].split(" ").join('|')}%") if params[:search].present?
|
||||
|
||||
@watchers_count = watchers.size
|
||||
@watchers = paginate(watchers)
|
||||
@@ -72,9 +73,13 @@ class UsersController < ApplicationController
|
||||
end
|
||||
|
||||
def update
|
||||
@user = User.find params[:id]
|
||||
@user.update!(user_params)
|
||||
render_ok
|
||||
return render_not_found unless @user = User.find_by_id(params[:id]) || User.find_by(login: params[:id])
|
||||
return render_forbidden unless User.current.logged? && (current_user&.admin? || current_user.id == @user.id)
|
||||
Util.write_file(@image, avatar_path(@user)) if user_params[:image].present?
|
||||
@user.attributes = user_params.except(:image)
|
||||
unless @user.save
|
||||
render_error(@user.errors.full_messages.join(", "))
|
||||
end
|
||||
end
|
||||
|
||||
def me
|
||||
@@ -274,11 +279,13 @@ class UsersController < ApplicationController
|
||||
end
|
||||
|
||||
def user_params
|
||||
params.require(:user).permit(:nickname, :lastname, :show_realname,:login,:mail,
|
||||
params.require(:user).permit(:nickname, :image,
|
||||
user_extension_attributes: [
|
||||
:gender, :location, :location_city,
|
||||
:occupation, :technical_title,
|
||||
:school_id, :department_id,:identity, :student_id, :description]
|
||||
:school_id, :department_id, :province, :city,
|
||||
:custom_department, :identity, :student_id, :description,
|
||||
:show_email, :show_location, :show_department]
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ class UsersForPrivateMessagesController < ApplicationController
|
||||
return
|
||||
end
|
||||
|
||||
users = users.where('LOWER(concat(lastname, firstname, nickname)) LIKE ?', "%#{keyword}%")
|
||||
users = users.where('LOWER(CONCAT_WS(lastname, firstname, nickname)) LIKE ?', "%#{keyword}%")
|
||||
|
||||
@users = users.limit(10).includes(:user_extension)
|
||||
end
|
||||
|
||||
@@ -86,7 +86,7 @@ class Weapps::CoursesController < Weapps::BaseController
|
||||
end
|
||||
|
||||
if search.present?
|
||||
@teacher_list = @teacher_list.joins(:user).where("LOWER(CONCAT(users.lastname, users.firstname)) like ?", "%#{search}%")
|
||||
@teacher_list = @teacher_list.joins(:user).where("LOWER(CONCAT_WS(users.lastname, users.firstname, users.nickname)) like ?", "%#{search}%")
|
||||
end
|
||||
|
||||
@teacher_list_size = @teacher_list.size
|
||||
@@ -127,7 +127,7 @@ class Weapps::CoursesController < Weapps::BaseController
|
||||
@students = CourseMember.students(@course)
|
||||
|
||||
if search.present?
|
||||
@students = @students.joins(user: :user_extension).where("LOWER(CONCAT(users.lastname, users.firstname)) like ? or
|
||||
@students = @students.joins(user: :user_extension).where("LOWER(CONCAT_WS(users.lastname, users.firstname, users.nickname)) like ? or
|
||||
user_extensions.student_id like ?", "%#{search}%", "%#{search}%")
|
||||
end
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ class ZipsController < ApplicationController
|
||||
|
||||
#搜索
|
||||
if params[:search].present?
|
||||
@ex_users = @ex_users.joins(user: :user_extension).where("CONCAT(lastname, firstname) like ? OR student_id like ?", "%#{params[:search]}%", "%#{params[:search]}%")
|
||||
@ex_users = @ex_users.joins(user: :user_extension).where("CONCAT_WS(lastname, firstname, nickname) like ? OR student_id like ?", "%#{params[:search]}%", "%#{params[:search]}%")
|
||||
end
|
||||
|
||||
default_ex_users_size = @ex_users&.size
|
||||
@@ -130,7 +130,7 @@ class ZipsController < ApplicationController
|
||||
end
|
||||
|
||||
unless params[:search].blank?
|
||||
@all_student_works = @all_student_works.joins(user: :user_extension).where("concat(lastname, firstname) like ?
|
||||
@all_student_works = @all_student_works.joins(user: :user_extension).where("CONCAT_WS(lastname, firstname, nickname) like ?
|
||||
or student_id like ?", "%#{params[:search]}%", "%#{params[:search]}%")
|
||||
end
|
||||
|
||||
|
||||
@@ -94,7 +94,7 @@ module TagChosenHelper
|
||||
|
||||
def render_issue_tags(project)
|
||||
# project.issue_tags.last&.cache_key
|
||||
cache_key = "all_issue_tags/#{project.issue_tags.maximum('updated_at')}"
|
||||
cache_key = "project-#{project.id}/all_issue_tags/size-#{project.issue_tags.size}/#{project.issue_tags.maximum('updated_at')}"
|
||||
|
||||
Rails.cache.fetch(cache_key) do
|
||||
project.issue_tags.select(:id, :name, :color).collect do |event|
|
||||
@@ -109,7 +109,7 @@ module TagChosenHelper
|
||||
end
|
||||
|
||||
def render_cache_milestones(project)
|
||||
cache_key = "all_milestones/#{project.versions.maximum('updated_on')}"
|
||||
cache_key = "project-#{project.id}/all_milestones/size-#{project.versions.size}/#{project.versions.maximum('updated_on')}"
|
||||
|
||||
Rails.cache.fetch(cache_key) do
|
||||
project.versions.select(:id, :name, :status).collect do |event|
|
||||
@@ -124,7 +124,7 @@ module TagChosenHelper
|
||||
end
|
||||
|
||||
def render_cache_collaborators(project)
|
||||
cache_key = "all_collaborators/#{project.all_collaborators.maximum('created_on')}"
|
||||
cache_key = "project-#{project.id}/all_collaborators/size-#{project.all_collaborators.size}/#{project.all_collaborators.maximum('updated_on')}"
|
||||
Rails.cache.fetch(cache_key) do
|
||||
project.all_collaborators.order(created_on: :desc).collect do |user|
|
||||
{
|
||||
|
||||
14
app/jobs/reset_platform_cache_job.rb
Normal file
14
app/jobs/reset_platform_cache_job.rb
Normal file
@@ -0,0 +1,14 @@
|
||||
class ResetPlatformCacheJob < ApplicationJob
|
||||
queue_as :cache
|
||||
|
||||
def perform
|
||||
Cache::PlatformFollowCountService.new.reset
|
||||
Cache::PlatformIssueCountService.new.reset
|
||||
Cache::PlatformProjectCountService.new.reset
|
||||
Cache::PlatformProjectForkCountService.new.reset
|
||||
Cache::PlatformProjectLanguagesCountService.new.reset
|
||||
Cache::PlatformProjectPraisesCountService.new.reset
|
||||
Cache::PlatformProjectWatchersCountService.new.reset
|
||||
Cache::PlatformPullrequestCountService.new.reset
|
||||
end
|
||||
end
|
||||
14
app/jobs/reset_user_cache_job.rb
Normal file
14
app/jobs/reset_user_cache_job.rb
Normal file
@@ -0,0 +1,14 @@
|
||||
class ResetUserCacheJob < ApplicationJob
|
||||
queue_as :cache
|
||||
|
||||
def perform(user)
|
||||
Cache::UserFollowCountService.new(user).reset
|
||||
Cache::UserIssueCountService.new(user).reset
|
||||
Cache::UserProjectCountService.new(user).reset
|
||||
Cache::UserProjectForkCountService.new(user).reset
|
||||
Cache::UserProjectLanguagesCountService.new(user).reset
|
||||
Cache::UserProjectPraisesCountService.new(user).reset
|
||||
Cache::UserProjectWatchersCountService.new(user).reset
|
||||
Cache::UserPullrequestCountService.new(user).reset
|
||||
end
|
||||
end
|
||||
@@ -5,7 +5,27 @@ class SyncMirroredRepositoryJob < ApplicationJob
|
||||
repo = Repository.find_by(id: repo_id)
|
||||
current_user = User.find_by(id: user_id)
|
||||
return if repo.blank? || current_user.blank?
|
||||
result = Gitea::Repository::SyncMirroredService.new(repo.owner.login, repo.identifier, token: current_user.gitea_token).call
|
||||
|
||||
# TODO
|
||||
# 先同步镜像库
|
||||
if repo.config_accelerator?
|
||||
puts "[gitea-accelerator]: ###### 镜像库开始同步 ######"
|
||||
result = Gitea::Accelerator::SyncMirroredService.call(repo.identifier)
|
||||
puts "[gitea-accelerator]: ###### 镜像库同步状态为 #{result[:status]}"
|
||||
|
||||
# TODO 暂时解决从镜像库镜像动作时间先执行的问题
|
||||
# 避免了Gitea::Repository::SyncMirroredService先执行后,加速器Gitea::Accelerator::SyncMirroredService
|
||||
# 再执行的导致Gitea::Repository::SyncMirroredService执行镜像不是最新代码的问题
|
||||
sleep 3.seconds
|
||||
end
|
||||
|
||||
sync_common!(repo, current_user)
|
||||
end
|
||||
|
||||
def sync_common!(repo, user)
|
||||
result = Gitea::Repository::SyncMirroredService.call(repo.owner.login,
|
||||
repo.identifier, token: user.gitea_token)
|
||||
repo&.mirror.set_status! if result[:status] === 200
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -16,4 +16,12 @@ class ApplicationRecord < ActiveRecord::Base
|
||||
def allow_sync_to_trustie?
|
||||
Rails.env.production? && EduSetting.get('host_name') == 'https://www.educoder.net'
|
||||
end
|
||||
|
||||
def reset_user_cache_async_job(user)
|
||||
ResetUserCacheJob.perform_later(user)
|
||||
end
|
||||
|
||||
def reset_platform_cache_async_job
|
||||
ResetPlatformCacheJob.perform_later
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,42 +1,42 @@
|
||||
# == 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 :string(255)
|
||||
# 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")
|
||||
# link :string(255)
|
||||
# clone_id :integer
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_attachments_on_author_id (author_id)
|
||||
# index_attachments_on_clone_id (clone_id)
|
||||
# index_attachments_on_container_id_and_container_type (container_id,container_type)
|
||||
# index_attachments_on_created_on (created_on)
|
||||
#
|
||||
|
||||
# == 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")
|
||||
#
|
||||
# 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)
|
||||
#
|
||||
|
||||
class Attachment < ApplicationRecord
|
||||
include BaseModel
|
||||
include Publicable
|
||||
@@ -51,7 +51,7 @@ class Attachment < ApplicationRecord
|
||||
# 二级目录
|
||||
# belongs_to :course_second_category, optional: true
|
||||
|
||||
scope :by_filename_or_user_name, -> (keywords) { joins(:author).where("filename like :search or LOWER(concat(users.lastname, users.firstname)) LIKE :search",
|
||||
scope :by_filename_or_user_name, -> (keywords) { joins(:author).where("filename like :search or LOWER(CONCAT_WS(users.lastname, users.firstname, users.nickname)) LIKE :search",
|
||||
:search => "%#{keywords.split(" ").join('|')}%") unless keywords.blank? }
|
||||
scope :by_keywords, -> (keywords) { where("filename LIKE ?", "%#{keywords.split(" ").join('|')}%") unless keywords.blank? }
|
||||
scope :ordered, -> (opts = {}) { order("#{opts[:sort_type]} #{opts[:sort] == 1 ? 'asc': 'desc'}") }
|
||||
|
||||
@@ -39,15 +39,13 @@
|
||||
# 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)
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
@@ -55,9 +53,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)
|
||||
#
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ module ProjectOperable
|
||||
has_many :reporters, -> { joins(:roles).where(roles: { name: 'Reporter' }) }, class_name: 'Member'
|
||||
has_many :writable_members, -> { joins(:roles).where.not(roles: {name: 'Reporter'}) }, class_name: 'Member'
|
||||
has_many :team_projects, dependent: :destroy
|
||||
has_many :teams, through: :team_projects, source: :team
|
||||
end
|
||||
|
||||
def set_owner_permission(creator)
|
||||
|
||||
@@ -20,4 +20,12 @@ class ForkUser < ApplicationRecord
|
||||
belongs_to :user
|
||||
belongs_to :fork_project, class_name: 'Project', foreign_key: :fork_project_id
|
||||
|
||||
after_save :reset_cache_data
|
||||
after_destroy :reset_cache_data
|
||||
|
||||
def reset_cache_data
|
||||
self.reset_platform_cache_async_job
|
||||
self.reset_user_cache_async_job(self.project.owner)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
# tracker_id :integer not null
|
||||
# project_id :integer not null
|
||||
# subject :string(255) default(""), not null
|
||||
# description :text(4294967295)
|
||||
# description :text(65535)
|
||||
# due_date :date
|
||||
# category_id :integer
|
||||
# status_id :integer not null
|
||||
@@ -14,6 +14,7 @@
|
||||
# priority_id :integer not null
|
||||
# fixed_version_id :integer
|
||||
# author_id :integer not null
|
||||
# lock_version :integer default("0"), not null
|
||||
# created_on :datetime
|
||||
# updated_on :datetime
|
||||
# start_date :date
|
||||
@@ -27,7 +28,7 @@
|
||||
# closed_on :datetime
|
||||
# project_issues_index :integer
|
||||
# issue_type :string(255)
|
||||
# token :integer default("0")
|
||||
# token :string(255)
|
||||
# issue_tags_value :string(255)
|
||||
# is_lock :boolean default("0")
|
||||
# issue_classify :string(255)
|
||||
@@ -50,7 +51,7 @@
|
||||
|
||||
class Issue < ApplicationRecord
|
||||
#issue_type 1为普通,2为悬赏
|
||||
belongs_to :project, :counter_cache => true
|
||||
belongs_to :project, counter_cache: true, touch: true
|
||||
belongs_to :tracker,optional: true
|
||||
has_many :project_trends, as: :trend, dependent: :destroy
|
||||
has_one :pull_request
|
||||
@@ -75,8 +76,13 @@ class Issue < ApplicationRecord
|
||||
scope :issue_index_includes, ->{includes(:tracker, :priority, :version, :issue_status, :journals,:issue_tags,user: :user_extension)}
|
||||
|
||||
after_update :change_versions_count
|
||||
after_destroy :update_closed_issues_count_in_project!
|
||||
after_save :reset_cache_data
|
||||
after_destroy :update_closed_issues_count_in_project!, :reset_cache_data
|
||||
|
||||
def reset_cache_data
|
||||
self.reset_platform_cache_async_job
|
||||
self.reset_user_cache_async_job(self.user)
|
||||
end
|
||||
|
||||
def get_assign_user
|
||||
User&.find_by_id(self.assigned_to_id) if self.assigned_to_id.present?
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
# sync_course :boolean default("0")
|
||||
# sync_subject :boolean default("0")
|
||||
# sync_shixun :boolean default("0")
|
||||
# is_local :boolean default("0")
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
|
||||
@@ -39,15 +39,13 @@
|
||||
# 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)
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
@@ -55,9 +53,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)
|
||||
#
|
||||
|
||||
|
||||
22
app/models/pinned_project.rb
Normal file
22
app/models/pinned_project.rb
Normal file
@@ -0,0 +1,22 @@
|
||||
# == Schema Information
|
||||
#
|
||||
# Table name: pinned_projects
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# user_id :integer
|
||||
# project_id :integer
|
||||
# position :integer default("0")
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_pinned_projects_on_project_id (project_id)
|
||||
# index_pinned_projects_on_user_id (user_id)
|
||||
#
|
||||
|
||||
class PinnedProject < ApplicationRecord
|
||||
|
||||
belongs_to :user
|
||||
belongs_to :project
|
||||
end
|
||||
@@ -1,26 +1,35 @@
|
||||
# == Schema Information
|
||||
#
|
||||
# Table name: praise_treads
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# user_id :integer not null
|
||||
# praise_tread_object_id :integer
|
||||
# praise_tread_object_type :string(255)
|
||||
# praise_or_tread :integer default("1")
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# praise_tread (praise_tread_object_id,praise_tread_object_type)
|
||||
#
|
||||
|
||||
# == Schema Information
|
||||
#
|
||||
# Table name: praise_treads
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# user_id :integer not null
|
||||
# praise_tread_object_id :integer
|
||||
# praise_tread_object_type :string(255)
|
||||
# praise_or_tread :integer default("1")
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# praise_tread (praise_tread_object_id,praise_tread_object_type)
|
||||
#
|
||||
|
||||
class PraiseTread < ApplicationRecord
|
||||
belongs_to :user
|
||||
belongs_to :praise_tread_object, polymorphic: true, counter_cache: :praises_count
|
||||
has_many :tidings, :as => :container, :dependent => :destroy
|
||||
|
||||
after_create :send_tiding
|
||||
after_save :reset_cache_data
|
||||
after_destroy :reset_cache_data
|
||||
|
||||
def reset_cache_data
|
||||
self.reset_platform_cache_async_job
|
||||
if self.praise_tread_object.is_a?(Project)
|
||||
self.reset_user_cache_async_job(self.praise_tread_object&.owner)
|
||||
end
|
||||
end
|
||||
|
||||
def send_tiding
|
||||
case self.praise_tread_object_type
|
||||
|
||||
@@ -1,76 +1,65 @@
|
||||
# == Schema Information
|
||||
#
|
||||
# Table name: projects
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# name :string(255) default(""), not null
|
||||
# description :text(4294967295)
|
||||
# homepage :string(255) default("")
|
||||
# is_public :boolean default("1"), not null
|
||||
# parent_id :integer
|
||||
# created_on :datetime
|
||||
# updated_on :datetime
|
||||
# identifier :string(255)
|
||||
# status :integer default("1"), not null
|
||||
# lft :integer
|
||||
# rgt :integer
|
||||
# inherit_members :boolean default("0"), not null
|
||||
# project_type :integer default("0")
|
||||
# hidden_repo :boolean default("0"), not null
|
||||
# attachmenttype :integer default("1")
|
||||
# user_id :integer
|
||||
# dts_test :integer default("0")
|
||||
# enterprise_name :string(255)
|
||||
# organization_id :integer
|
||||
# project_new_type :integer
|
||||
# gpid :integer
|
||||
# forked_from_project_id :integer
|
||||
# forked_count :integer default("0")
|
||||
# publish_resource :integer default("0")
|
||||
# visits :integer default("0")
|
||||
# hot :integer default("0")
|
||||
# invite_code :string(255)
|
||||
# qrcode :string(255)
|
||||
# qrcode_expiretime :integer default("0")
|
||||
# script :text(65535)
|
||||
# training_status :integer default("0")
|
||||
# rep_identifier :string(255)
|
||||
# project_category_id :integer
|
||||
# project_language_id :integer
|
||||
# praises_count :integer default("0")
|
||||
# watchers_count :integer default("0")
|
||||
# issues_count :integer default("0")
|
||||
# pull_requests_count :integer default("0")
|
||||
# language :string(255)
|
||||
# versions_count :integer default("0")
|
||||
# issue_tags_count :integer default("0")
|
||||
# closed_issues_count :integer default("0")
|
||||
# open_devops :boolean default("0")
|
||||
# gitea_webhook_id :integer
|
||||
# open_devops_count :integer default("0")
|
||||
# recommend :boolean default("0")
|
||||
# platform :integer default("0")
|
||||
# license_id :integer
|
||||
# ignore_id :integer
|
||||
# default_branch :string(255) default("master")
|
||||
# website :string(255)
|
||||
# lesson_url :string(255)
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_projects_on_forked_from_project_id (forked_from_project_id)
|
||||
# index_projects_on_identifier (identifier)
|
||||
# index_projects_on_is_public (is_public)
|
||||
# index_projects_on_lft (lft)
|
||||
# index_projects_on_name (name)
|
||||
# index_projects_on_platform (platform)
|
||||
# index_projects_on_project_type (project_type)
|
||||
# index_projects_on_recommend (recommend)
|
||||
# index_projects_on_rgt (rgt)
|
||||
# index_projects_on_status (status)
|
||||
# index_projects_on_updated_on (updated_on)
|
||||
#
|
||||
|
||||
# == Schema Information
|
||||
#
|
||||
# Table name: projects
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# name :string(255) default(""), not null
|
||||
# description :text(65535)
|
||||
# homepage :string(255) default("")
|
||||
# is_public :boolean default("1"), not null
|
||||
# parent_id :integer
|
||||
# created_on :datetime
|
||||
# updated_on :datetime
|
||||
# identifier :string(255)
|
||||
# status :integer default("1"), not null
|
||||
# lft :integer
|
||||
# rgt :integer
|
||||
# inherit_members :boolean default("0"), not null
|
||||
# project_type :integer default("0")
|
||||
# hidden_repo :boolean default("0"), not null
|
||||
# attachmenttype :integer default("1")
|
||||
# user_id :integer
|
||||
# dts_test :integer default("0")
|
||||
# enterprise_name :string(255)
|
||||
# organization_id :integer
|
||||
# project_new_type :integer
|
||||
# gpid :integer
|
||||
# forked_from_project_id :integer
|
||||
# forked_count :integer default("0")
|
||||
# publish_resource :integer default("0")
|
||||
# visits :integer default("0")
|
||||
# hot :integer default("0")
|
||||
# invite_code :string(255)
|
||||
# qrcode :string(255)
|
||||
# qrcode_expiretime :integer default("0")
|
||||
# script :text(65535)
|
||||
# training_status :integer default("0")
|
||||
# rep_identifier :string(255)
|
||||
# project_category_id :integer
|
||||
# project_language_id :integer
|
||||
# license_id :integer
|
||||
# ignore_id :integer
|
||||
# praises_count :integer default("0")
|
||||
# watchers_count :integer default("0")
|
||||
# issues_count :integer default("0")
|
||||
# pull_requests_count :integer default("0")
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_projects_on_forked_from_project_id (forked_from_project_id)
|
||||
# index_projects_on_identifier (identifier)
|
||||
# index_projects_on_is_public (is_public)
|
||||
# index_projects_on_lft (lft)
|
||||
# index_projects_on_name (name)
|
||||
# index_projects_on_platform (platform)
|
||||
# index_projects_on_project_type (project_type)
|
||||
# index_projects_on_recommend (recommend)
|
||||
# index_projects_on_rgt (rgt)
|
||||
# index_projects_on_status (status)
|
||||
# index_projects_on_updated_on (updated_on)
|
||||
#
|
||||
|
||||
|
||||
|
||||
class Project < ApplicationRecord
|
||||
include Matchable
|
||||
@@ -111,11 +100,13 @@ class Project < ApplicationRecord
|
||||
has_many :praise_treads, as: :praise_tread_object, dependent: :destroy
|
||||
has_and_belongs_to_many :trackers, :order => "#{Tracker.table_name}.position"
|
||||
has_one :project_detail, dependent: :destroy
|
||||
has_many :team_projects, dependent: :destroy
|
||||
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
|
||||
|
||||
after_save :check_project_members
|
||||
after_save :check_project_members, :reset_cache_data
|
||||
after_destroy :reset_cache_data
|
||||
scope :project_statics_select, -> {select(:id,:name, :is_public, :identifier, :status, :project_type, :user_id, :forked_count, :visits, :project_category_id, :project_language_id, :license_id, :ignore_id, :watchers_count, :created_on)}
|
||||
scope :no_anomory_projects, -> {where("projects.user_id is not null and projects.user_id != ?", 2)}
|
||||
scope :recommend, -> { visible.project_statics_select.where(recommend: true) }
|
||||
@@ -123,6 +114,14 @@ class Project < ApplicationRecord
|
||||
delegate :content, to: :project_detail, allow_nil: true
|
||||
delegate :name, to: :license, prefix: true, allow_nil: true
|
||||
|
||||
def reset_cache_data
|
||||
if changes[:user_id].present?
|
||||
first_owner = Owner.find_by_id(changes[:user_id].first)
|
||||
self.reset_user_cache_async_job(first_owner)
|
||||
end
|
||||
self.reset_platform_cache_async_job
|
||||
self.reset_user_cache_async_job(self.owner)
|
||||
end
|
||||
|
||||
def self.search_project(search)
|
||||
ransack(name_or_identifier_cont: search)
|
||||
|
||||
@@ -8,6 +8,11 @@
|
||||
# projects_count :integer default("0")
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# ancestry :string(255)
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_project_categories_on_ancestry (ancestry)
|
||||
#
|
||||
|
||||
class ProjectCategory < ApplicationRecord
|
||||
|
||||
@@ -16,11 +16,6 @@
|
||||
# head :string(255)
|
||||
# base :string(255)
|
||||
# issue_id :integer
|
||||
# fork_project_id :integer
|
||||
# is_original :boolean default("0")
|
||||
# comments_count :integer default("0")
|
||||
# commits_count :integer default("0")
|
||||
# files_count :integer default("0")
|
||||
#
|
||||
|
||||
class PullRequest < ApplicationRecord
|
||||
@@ -31,13 +26,21 @@ class PullRequest < ApplicationRecord
|
||||
|
||||
belongs_to :issue
|
||||
belongs_to :user
|
||||
belongs_to :project, :counter_cache => true
|
||||
belongs_to :project, counter_cache: true, touch: true
|
||||
# belongs_to :fork_project, foreign_key: :fork_project_id
|
||||
has_many :pull_request_assigns, foreign_key: :pull_request_id
|
||||
has_many :pull_request_tags, foreign_key: :pull_request_id
|
||||
has_many :project_trends, as: :trend, dependent: :destroy
|
||||
has_many :attachments, as: :container, dependent: :destroy
|
||||
|
||||
after_save :reset_cache_data
|
||||
after_destroy :reset_cache_data
|
||||
|
||||
def reset_cache_data
|
||||
self.reset_platform_cache_async_job
|
||||
self.reset_user_cache_async_job(self.user)
|
||||
end
|
||||
|
||||
def fork_project
|
||||
Project.find_by(id: self.fork_project_id)
|
||||
end
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_repositories_on_identifier (identifier)
|
||||
# index_repositories_on_project_id (project_id)
|
||||
# index_repositories_on_user_id (user_id)
|
||||
#
|
||||
@@ -82,5 +83,8 @@ class Repository < ApplicationRecord
|
||||
source_clone_url.blank? ? mirror_url : source_clone_url
|
||||
end
|
||||
|
||||
def config_accelerator?
|
||||
!source_clone_url.blank?
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -39,15 +39,13 @@
|
||||
# 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)
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
@@ -55,9 +53,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)
|
||||
#
|
||||
|
||||
@@ -164,11 +161,16 @@ class User < Owner
|
||||
|
||||
has_many :organization_users, dependent: :destroy
|
||||
has_many :organizations, through: :organization_users
|
||||
has_many :pinned_projects, dependent: :destroy
|
||||
has_many :is_pinned_projects, through: :pinned_projects, source: :project
|
||||
accepts_nested_attributes_for :is_pinned_projects
|
||||
has_many :issues, dependent: :destroy, foreign_key: :author_id
|
||||
has_many :pull_requests, dependent: :destroy
|
||||
|
||||
# Groups and active users
|
||||
scope :active, lambda { where(status: STATUS_ACTIVE) }
|
||||
scope :like, lambda { |keywords|
|
||||
sql = "CONCAT(lastname, firstname) LIKE :keyword OR login LIKE :keyword OR mail LIKE :keyword OR nickname LIKE :keyword"
|
||||
sql = "CONCAT_WS(lastname, firstname, nickname) LIKE :search OR login LIKE :search OR mail LIKE :search OR nickname LIKE :search"
|
||||
where(sql, :search => "%#{keywords.split(" ").join('|')}%") unless keywords.blank?
|
||||
}
|
||||
|
||||
@@ -176,7 +178,9 @@ class User < Owner
|
||||
|
||||
attr_accessor :password, :password_confirmation
|
||||
|
||||
delegate :gender, :department_id, :school_id, :location, :location_city, :technical_title, to: :user_extension, allow_nil: true
|
||||
delegate :description, :gender, :department_id, :school_id, :location, :location_city,
|
||||
:show_email, :show_location, :show_department,
|
||||
:technical_title, :province, :city, :custom_department, to: :user_extension, allow_nil: true
|
||||
|
||||
before_save :update_hashed_password
|
||||
after_create do
|
||||
@@ -195,6 +199,13 @@ class User < Owner
|
||||
validate :validate_sensitive_string
|
||||
validate :validate_password_length
|
||||
|
||||
# 用户参与的所有项目
|
||||
def full_member_projects
|
||||
normal_projects = Project.members_projects(self.id).to_sql
|
||||
org_projects = Project.joins(teams: :team_users).where(team_users: {user_id: self.id}).to_sql
|
||||
return Project.from("( #{ normal_projects} UNION #{ org_projects } ) AS projects").distinct
|
||||
end
|
||||
|
||||
def name
|
||||
login
|
||||
end
|
||||
|
||||
@@ -12,9 +12,7 @@
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_user_actions_on_ip (ip)
|
||||
# index_user_actions_on_user_id (user_id)
|
||||
# index_user_actions_on_user_id_and_action_type (user_id,action_type)
|
||||
# index_user_actions_on_ip (ip)
|
||||
#
|
||||
|
||||
class UserAction < ApplicationRecord
|
||||
|
||||
@@ -10,13 +10,10 @@
|
||||
# updated_at :datetime not null
|
||||
# register_status :integer default("0")
|
||||
# action_status :integer default("0")
|
||||
# is_delete :boolean default("0")
|
||||
# user_id :integer
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_user_agents_on_ip (ip)
|
||||
# index_user_agents_on_user_id (user_id)
|
||||
# index_user_agents_on_ip (ip) UNIQUE
|
||||
#
|
||||
|
||||
class UserAgent < ApplicationRecord
|
||||
|
||||
@@ -22,9 +22,12 @@
|
||||
# school_id :integer
|
||||
# description :string(255) default("")
|
||||
# department_id :integer
|
||||
# honor :text(65535)
|
||||
# edu_background :integer
|
||||
# edu_entry_year :integer
|
||||
# province :string(255)
|
||||
# city :string(255)
|
||||
# custom_department :string(255)
|
||||
# show_email :boolean default("0")
|
||||
# show_location :boolean default("0")
|
||||
# show_department :boolean default("0")
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
@@ -33,25 +36,25 @@
|
||||
# index_user_extensions_on_user_id (user_id)
|
||||
#
|
||||
|
||||
class UserExtension < ApplicationRecord
|
||||
# identity 0: 教师教授 1: 学生, 2: 专业人士, 3: 开发者
|
||||
enum identity: { teacher: 0, student: 1, professional: 2, developer: 3, enterprise: 4, unselect: -1 }
|
||||
|
||||
belongs_to :user, touch: true
|
||||
belongs_to :school, optional: true
|
||||
# belongs_to :department, optional: true
|
||||
|
||||
# before_save :set_laboratory_school
|
||||
|
||||
def identity_text
|
||||
I18n.t("user.identity.#{identity}")
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_laboratory_school
|
||||
# return unless new_record?
|
||||
|
||||
# self.school_id = Laboratory.current.school_id if school_id.blank? && !Laboratory.current.main_site?
|
||||
end
|
||||
end
|
||||
class UserExtension < ApplicationRecord
|
||||
# identity 0: 教师教授 1: 学生, 2: 专业人士, 3: 开发者
|
||||
enum identity: { teacher: 0, student: 1, professional: 2, developer: 3, enterprise: 4, unselect: -1 }
|
||||
|
||||
belongs_to :user, touch: true
|
||||
belongs_to :school, optional: true
|
||||
# belongs_to :department, optional: true
|
||||
|
||||
# before_save :set_laboratory_school
|
||||
|
||||
def identity_text
|
||||
I18n.t("user.identity.#{identity}")
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_laboratory_school
|
||||
# return unless new_record?
|
||||
|
||||
# self.school_id = Laboratory.current.school_id if school_id.blank? && !Laboratory.current.main_site?
|
||||
end
|
||||
end
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#
|
||||
|
||||
class Version < ApplicationRecord
|
||||
belongs_to :project, counter_cache: true
|
||||
belongs_to :project, counter_cache: true, touch: true
|
||||
has_many :issues, class_name: "Issue", foreign_key: "fixed_version_id"
|
||||
belongs_to :user, optional: true
|
||||
|
||||
|
||||
@@ -15,10 +15,24 @@
|
||||
# watchers_user_id_type (user_id,watchable_type)
|
||||
#
|
||||
|
||||
class Watcher < ApplicationRecord
|
||||
belongs_to :user
|
||||
|
||||
belongs_to :watchable, polymorphic: true, counter_cache: :watchers_count
|
||||
|
||||
scope :watching_users, ->(watchable_id){ where("watchable_type = ? and user_id = ?",'User',watchable_id)}
|
||||
end
|
||||
class Watcher < ApplicationRecord
|
||||
belongs_to :user
|
||||
|
||||
belongs_to :watchable, polymorphic: true, counter_cache: :watchers_count
|
||||
|
||||
scope :watching_users, ->(watchable_id){ where("watchable_type = ? and user_id = ?",'User',watchable_id)}
|
||||
|
||||
after_save :reset_cache_data
|
||||
after_destroy :reset_cache_data
|
||||
|
||||
def reset_cache_data
|
||||
if self.watchable.is_a?(User)
|
||||
self.reset_user_cache_async_job(self.watchable)
|
||||
end
|
||||
if self.watchable.is_a?(Project)
|
||||
self.reset_user_cache_async_job(self.watchable&.owner)
|
||||
end
|
||||
self.reset_platform_cache_async_job
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -26,7 +26,7 @@ class Admins::ApplyItemBankQuery < ApplicationQuery
|
||||
keyword = params[:keyword].to_s.strip
|
||||
if keyword.present?
|
||||
applies = applies.joins(user: { user_extension: :school })
|
||||
.where('CONCAT(lastname,firstname) LIKE :keyword OR schools.name LIKE :keyword', keyword: "%#{keyword}%")
|
||||
.where('CONCAT_WS(lastname,firstname, nickname) LIKE :keyword OR schools.name LIKE :keyword', keyword: "%#{keyword}%")
|
||||
end
|
||||
|
||||
custom_sort(applies, params[:sort_by], params[:sort_direction])
|
||||
|
||||
@@ -26,7 +26,7 @@ class Admins::ApplyUserAuthenticationQuery < ApplicationQuery
|
||||
keyword = params[:keyword].to_s.strip
|
||||
if keyword.present?
|
||||
applies = applies.joins(user: { user_extension: :school })
|
||||
.where('CONCAT(lastname,firstname) LIKE :keyword OR schools.name LIKE :keyword', keyword: "%#{keyword}%")
|
||||
.where('CONCAT_WS(lastname,firstname,nickname) LIKE :keyword OR schools.name LIKE :keyword', keyword: "%#{keyword}%")
|
||||
end
|
||||
|
||||
custom_sort(applies, params[:sort_by], params[:sort_direction])
|
||||
|
||||
@@ -19,7 +19,7 @@ class Admins::CourseListQuery < ApplicationQuery
|
||||
case search_type
|
||||
when "0"
|
||||
course_lists = course_lists.joins(:user)
|
||||
.where('CONCAT(lastname, firstname) like :keyword', keyword: "%#{keyword}%")
|
||||
.where('CONCAT_WS(lastname, firstname, nickname) like :keyword', keyword: "%#{keyword}%")
|
||||
when "1"
|
||||
course_lists = course_lists.where('name like :keyword', keyword: "%#{keyword}%")
|
||||
end
|
||||
|
||||
@@ -35,7 +35,7 @@ class Admins::CourseQuery < ApplicationQuery
|
||||
# 关键字
|
||||
keyword = params[:keyword].to_s.strip
|
||||
if keyword
|
||||
sql = 'CONCAT(lastname, firstname) LIKE :keyword OR courses.name LIKE :keyword OR course_lists.name LIKE :keyword'
|
||||
sql = 'CONCAT_WS(lastname, firstname, nickname) LIKE :keyword OR courses.name LIKE :keyword OR course_lists.name LIKE :keyword'
|
||||
courses = courses.joins(:teacher, :course_list).where(sql, keyword: "%#{keyword}%")
|
||||
end
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ class Admins::LaboratoryShixunQuery < ApplicationQuery
|
||||
|
||||
keyword = params[:keyword].to_s.strip
|
||||
if keyword.present?
|
||||
like_sql = 'shixuns.name LIKE :keyword OR CONCAT(users.lastname, users.firstname) LIKE :keyword'
|
||||
like_sql = 'shixuns.name LIKE :keyword OR CONCAT_WS(users.lastname, users.firstname, users.nickname) LIKE :keyword'
|
||||
laboratory_shixuns = laboratory_shixuns.joins(shixun: :user).where(like_sql, keyword: "%#{keyword}%")
|
||||
end
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ class Admins::LaboratorySubjectQuery < ApplicationQuery
|
||||
|
||||
keyword = params[:keyword].to_s.strip
|
||||
if keyword.present?
|
||||
like_sql = 'subjects.name LIKE :keyword OR CONCAT(users.lastname, users.firstname) LIKE :keyword'
|
||||
like_sql = 'subjects.name LIKE :keyword OR CONCAT_WS(users.lastname, users.firstname, users.nickname) LIKE :keyword'
|
||||
laboratory_subjects = laboratory_subjects.joins(subject: :user).where(like_sql, keyword: "%#{keyword}%")
|
||||
end
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ class Admins::SubjectQuery < ApplicationQuery
|
||||
# 关键字
|
||||
keyword = params[:keyword].to_s.strip
|
||||
if keyword
|
||||
sql = 'CONCAT(lastname, firstname) LIKE :keyword OR subjects.name LIKE :keyword'
|
||||
sql = 'CONCAT_WS(lastname, firstname, nickname) LIKE :keyword OR subjects.name LIKE :keyword'
|
||||
subjects = subjects.joins(:user).where(sql, keyword: "%#{keyword}%")
|
||||
end
|
||||
|
||||
|
||||
@@ -30,14 +30,14 @@ class Admins::UserQuery < ApplicationQuery
|
||||
# 关键字检索
|
||||
keyword = params[:keyword].to_s.strip.presence
|
||||
if keyword
|
||||
sql = 'CONCAT(lastname, firstname) LIKE :keyword OR login LIKE :keyword OR mail LIKE :keyword OR phone LIKE :keyword'
|
||||
sql = 'CONCAT_WS(lastname, firstname, nickname) LIKE :keyword OR login LIKE :keyword OR mail LIKE :keyword OR phone LIKE :keyword'
|
||||
users = users.where(sql, keyword: "%#{keyword}%")
|
||||
end
|
||||
|
||||
# 姓名
|
||||
name = params[:name].to_s.strip.presence
|
||||
if name.present?
|
||||
users = users.where('CONCAT(lastname, firstname) LIKE :name', name: "%#{name}%")
|
||||
users = users.where('CONCAT_WS(lastname, firstname, nickname) LIKE :name', name: "%#{name}%")
|
||||
end
|
||||
|
||||
# 单位ID
|
||||
|
||||
@@ -53,10 +53,15 @@ class Projects::ListMyQuery < ApplicationQuery
|
||||
|
||||
q = projects.ransack(name_or_identifier_cont: params[:search])
|
||||
|
||||
scope = q.result.includes(:project_category, :project_language,:owner, :repository)
|
||||
scope = q.result.includes(:project_category, :project_language,:owner, :repository, :has_pinned_users)
|
||||
|
||||
sort = params[:sort_by] || "updated_on"
|
||||
sort_direction = params[:sort_direction] || "desc"
|
||||
scope.order("projects.#{sort} #{sort_direction}")
|
||||
|
||||
if params[:choosed].present? && params[:choosed].is_a?(Array)
|
||||
scope.order("FIELD(id, #{params[:choosed].reverse.join(",")}) desc")
|
||||
else
|
||||
scope.order("projects.#{sort} #{sort_direction}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -10,7 +10,7 @@ class UserQuery < ApplicationQuery
|
||||
|
||||
# 真实姓名
|
||||
if name = strip_param(:name)
|
||||
users = users.where('LOWER(CONCAT(users.lastname, users.firstname)) LIKE ?', "%#{name.downcase}%")
|
||||
users = users.where('LOWER(CONCAT_WS(users.lastname, users.firstname, users.nickname)) LIKE ?', "%#{name.downcase}%")
|
||||
end
|
||||
|
||||
# 单位名称
|
||||
|
||||
@@ -84,7 +84,7 @@ class Admins::ImportUserService < ApplicationService
|
||||
if data.identity.to_i == 1
|
||||
users = users.where(user_extensions: { student_id: data.student_id })
|
||||
else
|
||||
users = users.where(user_extensions: { technical_title: data.technical_title }).where('CONCAT(users.lastname,users.firstname) = ?', data.name)
|
||||
users = users.where(user_extensions: { technical_title: data.technical_title }).where('CONCAT_WS(users.lastname,users.firstname,users.nickname) = ?', data.name)
|
||||
end
|
||||
|
||||
users.first
|
||||
|
||||
41
app/services/cache/platform_follow_count_service.rb
vendored
Normal file
41
app/services/cache/platform_follow_count_service.rb
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
class Cache::PlatformFollowCountService < ApplicationService
|
||||
attr_reader :increment_count
|
||||
|
||||
def initialize(increment_count=0)
|
||||
@increment_count = increment_count
|
||||
end
|
||||
|
||||
def call
|
||||
set_platform_follow_count
|
||||
|
||||
platform_follow_count
|
||||
end
|
||||
|
||||
def reset
|
||||
reset_platform_follow_count
|
||||
|
||||
platform_follow_count
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def platform_follow_count_key
|
||||
"platform-follow-count"
|
||||
end
|
||||
|
||||
def platform_follow_count
|
||||
$redis_cache.get(platform_follow_count_key).to_i
|
||||
end
|
||||
|
||||
def set_platform_follow_count
|
||||
if $redis_cache.exists(platform_follow_count_key)
|
||||
$redis_cache.incrby(platform_follow_count_key, increment_count)
|
||||
else
|
||||
reset_platform_follow_count
|
||||
end
|
||||
end
|
||||
|
||||
def reset_platform_follow_count
|
||||
$redis_cache.set(platform_follow_count_key, Watcher.where(watchable_type: 'User').count)
|
||||
end
|
||||
end
|
||||
41
app/services/cache/platform_issue_count_service.rb
vendored
Normal file
41
app/services/cache/platform_issue_count_service.rb
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
class Cache::PlatformIssueCountService < ApplicationService
|
||||
attr_reader :increment_count
|
||||
|
||||
def initialize(increment_count=0)
|
||||
@increment_count = increment_count
|
||||
end
|
||||
|
||||
def call
|
||||
set_platform_issue_count
|
||||
|
||||
platform_issue_count
|
||||
end
|
||||
|
||||
def reset
|
||||
reset_platform_issue_count
|
||||
|
||||
platform_issue_count
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def platform_issue_count_key
|
||||
"platform-issue-count"
|
||||
end
|
||||
|
||||
def platform_issue_count
|
||||
$redis_cache.get(platform_issue_count_key).to_i
|
||||
end
|
||||
|
||||
def set_platform_issue_count
|
||||
if $redis_cache.exists(platform_issue_count_key)
|
||||
$redis_cache.incrby(platform_issue_count_key, increment_count)
|
||||
else
|
||||
reset_platform_issue_count
|
||||
end
|
||||
end
|
||||
|
||||
def reset_platform_issue_count
|
||||
$redis_cache.set(platform_issue_count_key, Issue.count)
|
||||
end
|
||||
end
|
||||
41
app/services/cache/platform_project_count_service.rb
vendored
Normal file
41
app/services/cache/platform_project_count_service.rb
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
class Cache::PlatformProjectCountService < ApplicationService
|
||||
attr_reader :increment_count
|
||||
|
||||
def initialize(increment_count=0)
|
||||
@increment_count = increment_count
|
||||
end
|
||||
|
||||
def call
|
||||
set_platform_project_count
|
||||
|
||||
platform_project_count
|
||||
end
|
||||
|
||||
def reset
|
||||
reset_platform_project_count
|
||||
|
||||
platform_project_count
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def platform_project_count_key
|
||||
"platform-project-count"
|
||||
end
|
||||
|
||||
def platform_project_count
|
||||
$redis_cache.get(platform_project_count_key).to_i
|
||||
end
|
||||
|
||||
def set_platform_project_count
|
||||
if $redis_cache.exists(platform_project_count_key)
|
||||
$redis_cache.incrby(platform_project_count_key, increment_count)
|
||||
else
|
||||
reset_platform_project_count
|
||||
end
|
||||
end
|
||||
|
||||
def reset_platform_project_count
|
||||
$redis_cache.set(platform_project_count_key, Project.count)
|
||||
end
|
||||
end
|
||||
41
app/services/cache/platform_project_fork_count_service.rb
vendored
Normal file
41
app/services/cache/platform_project_fork_count_service.rb
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
class Cache::PlatformProjectForkCountService < ApplicationService
|
||||
attr_reader :increment_count
|
||||
|
||||
def initialize(increment_count=0)
|
||||
@increment_count = increment_count
|
||||
end
|
||||
|
||||
def call
|
||||
set_platform_project_fork_count
|
||||
|
||||
platform_project_fork_count
|
||||
end
|
||||
|
||||
def reset
|
||||
reset_platform_project_fork_count
|
||||
|
||||
platform_project_fork_count
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def platform_project_fork_count_key
|
||||
"platform-project-fork-count"
|
||||
end
|
||||
|
||||
def platform_project_fork_count
|
||||
$redis_cache.get(platform_project_fork_count_key).to_i
|
||||
end
|
||||
|
||||
def set_platform_project_fork_count
|
||||
if $redis_cache.exists(platform_project_fork_count_key)
|
||||
$redis_cache.incrby(platform_project_fork_count_key, increment_count)
|
||||
else
|
||||
reset_platform_project_fork_count
|
||||
end
|
||||
end
|
||||
|
||||
def reset_platform_project_fork_count
|
||||
$redis_cache.set(platform_project_fork_count_key, ForkUser.count)
|
||||
end
|
||||
end
|
||||
57
app/services/cache/platform_project_languages_count_service.rb
vendored
Normal file
57
app/services/cache/platform_project_languages_count_service.rb
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
class Cache::PlatformProjectLanguagesCountService < ApplicationService
|
||||
attr_reader :key, :increment_count
|
||||
|
||||
def initialize(key=nil, increment_count=0)
|
||||
@key = key
|
||||
@increment_count = increment_count
|
||||
end
|
||||
|
||||
def call
|
||||
set_platform_project_language_count
|
||||
|
||||
platform_project_language_count
|
||||
end
|
||||
|
||||
def reset_by_key
|
||||
reset_platform_project_language_count_by_key
|
||||
|
||||
platform_project_language_count
|
||||
end
|
||||
|
||||
def reset
|
||||
reset_platform_project_language_count
|
||||
|
||||
platform_project_language_count
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def platform_project_language_count_key
|
||||
"platform-project-language-count"
|
||||
end
|
||||
|
||||
def platform_project_language_count
|
||||
$redis_cache.hgetall(platform_project_language_count_key).transform_values(&:to_i)
|
||||
end
|
||||
|
||||
def set_platform_project_language_count
|
||||
if $redis_cache.hlen(platform_project_language_count_key) == 0
|
||||
reset_platform_project_language_count
|
||||
elsif $redis_cache.hget(platform_project_language_count_key, key).nil?
|
||||
reset_platform_project_language_count_by_key
|
||||
else
|
||||
$redis_cache.hincrby(platform_project_language_count_key, key, increment_count)
|
||||
end
|
||||
end
|
||||
|
||||
def reset_platform_project_language_count_by_key
|
||||
return if key.nil?
|
||||
$redis_cache.hset(platform_project_language_count_key, key, Project.joins(:project_language).where(project_languages: {name: key}).count)
|
||||
end
|
||||
|
||||
def reset_platform_project_language_count
|
||||
Project.joins(:project_language).group("project_languages.name").count.each do |k, v|
|
||||
$redis_cache.hset(platform_project_language_count_key, k, v)
|
||||
end
|
||||
end
|
||||
end
|
||||
41
app/services/cache/platform_project_praises_count_service.rb
vendored
Normal file
41
app/services/cache/platform_project_praises_count_service.rb
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
class Cache::PlatformProjectPraisesCountService < ApplicationService
|
||||
attr_reader :increment_count
|
||||
|
||||
def initialize(increment_count=0)
|
||||
@increment_count = increment_count
|
||||
end
|
||||
|
||||
def call
|
||||
set_platform_project_praises_count
|
||||
|
||||
platform_project_praises_count
|
||||
end
|
||||
|
||||
def reset
|
||||
reset_platform_project_praises_count
|
||||
|
||||
platform_project_praises_count
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def platform_project_praises_count_key
|
||||
"platform-project-praises-count"
|
||||
end
|
||||
|
||||
def platform_project_praises_count
|
||||
$redis_cache.get(platform_project_praises_count_key).to_i
|
||||
end
|
||||
|
||||
def set_platform_project_praises_count
|
||||
if $redis_cache.exists(platform_project_praises_count_key)
|
||||
$redis_cache.incrby(platform_project_praises_count_key, increment_count)
|
||||
else
|
||||
reset_platform_project_praises_count
|
||||
end
|
||||
end
|
||||
|
||||
def reset_platform_project_praises_count
|
||||
$redis_cache.set(platform_project_praises_count_key, PraiseTread.where(praise_tread_object_type: "Project").count)
|
||||
end
|
||||
end
|
||||
41
app/services/cache/platform_project_watchers_count_service.rb
vendored
Normal file
41
app/services/cache/platform_project_watchers_count_service.rb
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
class Cache::PlatformProjectWatchersCountService < ApplicationService
|
||||
attr_reader :increment_count
|
||||
|
||||
def initialize(increment_count=0)
|
||||
@increment_count = increment_count
|
||||
end
|
||||
|
||||
def call
|
||||
set_platform_project_watchers_count
|
||||
|
||||
platform_project_watchers_count
|
||||
end
|
||||
|
||||
def reset
|
||||
reset_platform_project_watchers_count
|
||||
|
||||
platform_project_watchers_count
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def platform_project_watchers_count_key
|
||||
"platform-project-watchers-count"
|
||||
end
|
||||
|
||||
def platform_project_watchers_count
|
||||
$redis_cache.get(platform_project_watchers_count_key).to_i
|
||||
end
|
||||
|
||||
def set_platform_project_watchers_count
|
||||
if $redis_cache.exists(platform_project_watchers_count_key)
|
||||
$redis_cache.incrby(platform_project_watchers_count_key, increment_count)
|
||||
else
|
||||
reset_platform_project_watchers_count
|
||||
end
|
||||
end
|
||||
|
||||
def reset_platform_project_watchers_count
|
||||
$redis_cache.set(platform_project_watchers_count_key, Watcher.where(watchable_type: 'Project').count)
|
||||
end
|
||||
end
|
||||
41
app/services/cache/platform_pullrequest_count_service.rb
vendored
Normal file
41
app/services/cache/platform_pullrequest_count_service.rb
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
class Cache::PlatformPullrequestCountService < ApplicationService
|
||||
attr_reader :increment_count
|
||||
|
||||
def initialize(increment_count=0)
|
||||
@increment_count = increment_count
|
||||
end
|
||||
|
||||
def call
|
||||
set_platform_pullrequest_count
|
||||
|
||||
platform_pullrequest_count
|
||||
end
|
||||
|
||||
def reset
|
||||
reset_platform_pullrequest_count
|
||||
|
||||
platform_pullrequest_count
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def platform_pullrequest_count_key
|
||||
"platform-pullrequest-count"
|
||||
end
|
||||
|
||||
def platform_pullrequest_count
|
||||
$redis_cache.get(platform_pullrequest_count_key).to_i
|
||||
end
|
||||
|
||||
def set_platform_pullrequest_count
|
||||
if $redis_cache.exists(platform_pullrequest_count_key)
|
||||
$redis_cache.incrby(platform_pullrequest_count_key, increment_count)
|
||||
else
|
||||
reset_platform_pullrequest_count
|
||||
end
|
||||
end
|
||||
|
||||
def reset_platform_pullrequest_count
|
||||
$redis_cache.set(platform_pullrequest_count_key, PullRequest.count)
|
||||
end
|
||||
end
|
||||
43
app/services/cache/user_follow_count_service.rb
vendored
Normal file
43
app/services/cache/user_follow_count_service.rb
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
class Cache::UserFollowCountService < ApplicationService
|
||||
attr_reader :user, :increment_count
|
||||
|
||||
def initialize(user, increment_count=0)
|
||||
@user = user
|
||||
@increment_count = increment_count
|
||||
end
|
||||
|
||||
def call
|
||||
set_user_follow_count
|
||||
|
||||
user_follow_count
|
||||
end
|
||||
|
||||
def reset
|
||||
reset_user_follow_count
|
||||
|
||||
user_follow_count
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def user_follow_count_key
|
||||
"user-follow-count-#{user.id}"
|
||||
end
|
||||
|
||||
def user_follow_count
|
||||
$redis_cache.get(user_follow_count_key).to_i
|
||||
end
|
||||
|
||||
def set_user_follow_count
|
||||
if $redis_cache.exists(user_follow_count_key)
|
||||
$redis_cache.incrby(user_follow_count_key, increment_count)
|
||||
else
|
||||
reset_user_follow_count
|
||||
end
|
||||
end
|
||||
|
||||
def reset_user_follow_count
|
||||
return if user.nil?
|
||||
$redis_cache.set(user_follow_count_key, Watcher.where(watchable: user).count)
|
||||
end
|
||||
end
|
||||
43
app/services/cache/user_issue_count_service.rb
vendored
Normal file
43
app/services/cache/user_issue_count_service.rb
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
class Cache::UserIssueCountService < ApplicationService
|
||||
attr_reader :user, :increment_count
|
||||
|
||||
def initialize(user, increment_count=0)
|
||||
@user = user
|
||||
@increment_count = increment_count
|
||||
end
|
||||
|
||||
def call
|
||||
set_user_issue_count
|
||||
|
||||
user_issue_count
|
||||
end
|
||||
|
||||
def reset
|
||||
reset_user_issue_count
|
||||
|
||||
user_issue_count
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def user_issue_count_key
|
||||
"user-issue-count-#{user.id}"
|
||||
end
|
||||
|
||||
def user_issue_count
|
||||
$redis_cache.get(user_issue_count_key).to_i
|
||||
end
|
||||
|
||||
def set_user_issue_count
|
||||
if $redis_cache.exists(user_issue_count_key)
|
||||
$redis_cache.incrby(user_issue_count_key, increment_count)
|
||||
else
|
||||
reset_user_issue_count
|
||||
end
|
||||
end
|
||||
|
||||
def reset_user_issue_count
|
||||
return if user.nil?
|
||||
$redis_cache.set(user_issue_count_key, Issue.where(author_id: user.id).count)
|
||||
end
|
||||
end
|
||||
43
app/services/cache/user_project_count_service.rb
vendored
Normal file
43
app/services/cache/user_project_count_service.rb
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
class Cache::UserProjectCountService < ApplicationService
|
||||
attr_reader :user, :increment_count
|
||||
|
||||
def initialize(user, increment_count=0)
|
||||
@user = user
|
||||
@increment_count = increment_count
|
||||
end
|
||||
|
||||
def call
|
||||
set_user_project_count
|
||||
|
||||
user_project_count
|
||||
end
|
||||
|
||||
def reset
|
||||
reset_user_project_count
|
||||
|
||||
user_project_count
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def user_project_count_key
|
||||
"user-project-count-#{user.id}"
|
||||
end
|
||||
|
||||
def user_project_count
|
||||
$redis_cache.get(user_project_count_key).to_i
|
||||
end
|
||||
|
||||
def set_user_project_count
|
||||
if $redis_cache.exists(user_project_count_key)
|
||||
$redis_cache.incrby(user_project_count_key, increment_count)
|
||||
else
|
||||
reset_user_project_count
|
||||
end
|
||||
end
|
||||
|
||||
def reset_user_project_count
|
||||
return if user.nil?
|
||||
$redis_cache.set(user_project_count_key, user.projects.count)
|
||||
end
|
||||
end
|
||||
43
app/services/cache/user_project_fork_count_service.rb
vendored
Normal file
43
app/services/cache/user_project_fork_count_service.rb
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
class Cache::UserProjectForkCountService < ApplicationService
|
||||
attr_reader :user, :increment_count
|
||||
|
||||
def initialize(user, increment_count=0)
|
||||
@user = user
|
||||
@increment_count = increment_count
|
||||
end
|
||||
|
||||
def call
|
||||
set_user_project_fork_count
|
||||
|
||||
user_project_fork_count
|
||||
end
|
||||
|
||||
def reset
|
||||
reset_user_project_fork_count
|
||||
|
||||
user_project_fork_count
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def user_project_fork_count_key
|
||||
"user-project-fork-count-#{user.id}"
|
||||
end
|
||||
|
||||
def user_project_fork_count
|
||||
$redis_cache.get(user_project_fork_count_key).to_i
|
||||
end
|
||||
|
||||
def set_user_project_fork_count
|
||||
if $redis_cache.exists(user_project_fork_count_key)
|
||||
$redis_cache.incrby(user_project_fork_count_key, increment_count)
|
||||
else
|
||||
reset_user_project_fork_count
|
||||
end
|
||||
end
|
||||
|
||||
def reset_user_project_fork_count
|
||||
return if user.nil?
|
||||
$redis_cache.set(user_project_fork_count_key, ForkUser.joins(:project).where(projects: {user_id: user.id}).count)
|
||||
end
|
||||
end
|
||||
60
app/services/cache/user_project_languages_count_service.rb
vendored
Normal file
60
app/services/cache/user_project_languages_count_service.rb
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
class Cache::UserProjectLanguagesCountService < ApplicationService
|
||||
attr_reader :user, :key, :increment_count
|
||||
|
||||
def initialize(user, key=nil, increment_count=0)
|
||||
@user = user
|
||||
@key = key
|
||||
@increment_count = increment_count
|
||||
end
|
||||
|
||||
def call
|
||||
set_user_project_language_count
|
||||
|
||||
user_project_language_count
|
||||
end
|
||||
|
||||
def reset_by_key
|
||||
reset_user_project_language_count_by_key
|
||||
|
||||
user_project_language_count
|
||||
end
|
||||
|
||||
def reset
|
||||
reset_user_project_language_count
|
||||
|
||||
user_project_language_count
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def user_project_language_count_key
|
||||
"user-project-language-count-#{user.id}"
|
||||
end
|
||||
|
||||
def user_project_language_count
|
||||
$redis_cache.hgetall(user_project_language_count_key).transform_values(&:to_i)
|
||||
end
|
||||
|
||||
def set_user_project_language_count
|
||||
if $redis_cache.hlen(user_project_language_count_key) == 0
|
||||
reset_user_project_language_count
|
||||
elsif $redis_cache.hget(user_project_language_count_key, key).nil?
|
||||
reset_user_project_language_count_by_key
|
||||
else
|
||||
$redis_cache.hincrby(user_project_language_count_key, key, increment_count)
|
||||
end
|
||||
end
|
||||
|
||||
def reset_user_project_language_count_by_key
|
||||
return if user.nil?
|
||||
return if key.nil?
|
||||
$redis_cache.hset(user_project_language_count_key, key, user.projects.joins(:project_language).where(project_languages: {name: key}).count)
|
||||
end
|
||||
|
||||
def reset_user_project_language_count
|
||||
return if user.nil?
|
||||
user.projects.joins(:project_language).group("project_languages.name").count.each do |k, v|
|
||||
$redis_cache.hset(user_project_language_count_key, k, v)
|
||||
end
|
||||
end
|
||||
end
|
||||
43
app/services/cache/user_project_praises_count_service.rb
vendored
Normal file
43
app/services/cache/user_project_praises_count_service.rb
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
class Cache::UserProjectPraisesCountService < ApplicationService
|
||||
attr_reader :user, :increment_count
|
||||
|
||||
def initialize(user, increment_count=0)
|
||||
@user = user
|
||||
@increment_count = increment_count
|
||||
end
|
||||
|
||||
def call
|
||||
set_user_project_praises_count
|
||||
|
||||
user_project_praises_count
|
||||
end
|
||||
|
||||
def reset
|
||||
reset_user_project_praises_count
|
||||
|
||||
user_project_praises_count
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def user_project_praises_count_key
|
||||
"user-project-praises-count-#{user.id}"
|
||||
end
|
||||
|
||||
def user_project_praises_count
|
||||
$redis_cache.get(user_project_praises_count_key).to_i
|
||||
end
|
||||
|
||||
def set_user_project_praises_count
|
||||
if $redis_cache.exists(user_project_praises_count_key)
|
||||
$redis_cache.incrby(user_project_praises_count_key, increment_count)
|
||||
else
|
||||
reset_user_project_praises_count
|
||||
end
|
||||
end
|
||||
|
||||
def reset_user_project_praises_count
|
||||
return if user.nil?
|
||||
$redis_cache.set(user_project_praises_count_key, PraiseTread.where(praise_tread_object_type: 'Project', praise_tread_object_id: user.projects).count)
|
||||
end
|
||||
end
|
||||
43
app/services/cache/user_project_watchers_count_service.rb
vendored
Normal file
43
app/services/cache/user_project_watchers_count_service.rb
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
class Cache::UserProjectWatchersCountService < ApplicationService
|
||||
attr_reader :user, :increment_count
|
||||
|
||||
def initialize(user, increment_count=0)
|
||||
@user = user
|
||||
@increment_count = increment_count
|
||||
end
|
||||
|
||||
def call
|
||||
set_user_project_watchers_count
|
||||
|
||||
user_project_watchers_count
|
||||
end
|
||||
|
||||
def reset
|
||||
reset_user_project_watchers_count
|
||||
|
||||
user_project_watchers_count
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def user_project_watchers_count_key
|
||||
"user-project-watchers-count-#{user.id}"
|
||||
end
|
||||
|
||||
def user_project_watchers_count
|
||||
$redis_cache.get(user_project_watchers_count_key).to_i
|
||||
end
|
||||
|
||||
def set_user_project_watchers_count
|
||||
if $redis_cache.exists(user_project_watchers_count_key)
|
||||
$redis_cache.incrby(user_project_watchers_count_key, increment_count)
|
||||
else
|
||||
reset_user_project_watchers_count
|
||||
end
|
||||
end
|
||||
|
||||
def reset_user_project_watchers_count
|
||||
return if user.nil?
|
||||
$redis_cache.set(user_project_watchers_count_key, Watcher.where(watchable_type: 'Project', watchable_id: user.projects).count)
|
||||
end
|
||||
end
|
||||
43
app/services/cache/user_pullrequest_count_service.rb
vendored
Normal file
43
app/services/cache/user_pullrequest_count_service.rb
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
class Cache::UserPullrequestCountService < ApplicationService
|
||||
attr_reader :user, :increment_count
|
||||
|
||||
def initialize(user, increment_count=0)
|
||||
@user = user
|
||||
@increment_count = increment_count
|
||||
end
|
||||
|
||||
def call
|
||||
set_user_pullrequest_count
|
||||
|
||||
user_pullrequest_count
|
||||
end
|
||||
|
||||
def reset
|
||||
reset_user_pullrequest_count
|
||||
|
||||
user_pullrequest_count
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def user_pullrequest_count_key
|
||||
"user-pullrequest-count-#{user.id}"
|
||||
end
|
||||
|
||||
def user_pullrequest_count
|
||||
$redis_cache.get(user_pullrequest_count_key).to_i
|
||||
end
|
||||
|
||||
def set_user_pullrequest_count
|
||||
if $redis_cache.exists(user_pullrequest_count_key)
|
||||
$redis_cache.incrby(user_pullrequest_count_key, increment_count)
|
||||
else
|
||||
reset_user_pullrequest_count
|
||||
end
|
||||
end
|
||||
|
||||
def reset_user_pullrequest_count
|
||||
return if user.nil?
|
||||
$redis_cache.set(user_pullrequest_count_key, PullRequest.where(user_id: user.id).count)
|
||||
end
|
||||
end
|
||||
96
app/services/gitea/accelerator/base_service.rb
Normal file
96
app/services/gitea/accelerator/base_service.rb
Normal file
@@ -0,0 +1,96 @@
|
||||
class Gitea::Accelerator::BaseService < ApplicationService
|
||||
|
||||
def post(url, params)
|
||||
puts "[gitea] request params: #{params}"
|
||||
puts "[gitea] access_username: #{access_username}"
|
||||
puts "[gitea] access_password: #{access_password}"
|
||||
conn.post do |req|
|
||||
req.url full_url(url)
|
||||
req.body = params.to_json
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def conn
|
||||
@client ||= begin
|
||||
Faraday.new(url: domain) do |req|
|
||||
req.request :url_encoded
|
||||
req.headers['Content-Type'] = 'application/json'
|
||||
req.response :logger # 显示日志
|
||||
req.adapter Faraday.default_adapter
|
||||
req.basic_auth(access_username, access_password)
|
||||
end
|
||||
end
|
||||
@client
|
||||
end
|
||||
|
||||
def base_url
|
||||
accelerator["base_url"]
|
||||
end
|
||||
|
||||
def domain
|
||||
accelerator["domain"]
|
||||
end
|
||||
|
||||
def api_url
|
||||
[domain, base_url].join('')
|
||||
end
|
||||
|
||||
def full_url(api_rest, action='post')
|
||||
url = [api_url, api_rest].join('').freeze
|
||||
url = action === 'get' ? url : URI.escape(url)
|
||||
puts "[gitea] request url: #{url}"
|
||||
url
|
||||
end
|
||||
|
||||
def access_username
|
||||
accelerator["access_key_id"]
|
||||
end
|
||||
|
||||
def access_password
|
||||
accelerator["access_key_secret"]
|
||||
end
|
||||
|
||||
def access_uid
|
||||
accelerator["access_admin_uid"]
|
||||
end
|
||||
|
||||
def accelerator
|
||||
Gitea.gitea_config[:accelerator]
|
||||
end
|
||||
|
||||
def render_status(response)
|
||||
puts "[gitea] response status: #{response.status}"
|
||||
puts "[gitea] response body: #{response.body}"
|
||||
case response.status
|
||||
when 201
|
||||
success
|
||||
when 403
|
||||
error('APIForbiddenError')
|
||||
when 422
|
||||
error('APIValidationError')
|
||||
else
|
||||
error("MigrateError")
|
||||
end
|
||||
end
|
||||
|
||||
def error(message)
|
||||
{
|
||||
status: :error,
|
||||
message: message,
|
||||
data: nil
|
||||
}
|
||||
end
|
||||
|
||||
def success(data=nil)
|
||||
{
|
||||
status: :success,
|
||||
message: nil,
|
||||
data: data
|
||||
}
|
||||
end
|
||||
|
||||
def check_accelerator!
|
||||
accelerator.blank? || access_username.blank? || access_password.blank? || domain.blank?
|
||||
end
|
||||
end
|
||||
@@ -1,4 +1,4 @@
|
||||
class Gitea::Accelerator::MigrateService < ApplicationService
|
||||
class Gitea::Accelerator::MigrateService < Gitea::Accelerator::BaseService
|
||||
attr_reader :params
|
||||
|
||||
# params description:
|
||||
@@ -36,8 +36,8 @@ class Gitea::Accelerator::MigrateService < ApplicationService
|
||||
render_status(response)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
private
|
||||
def request_params
|
||||
{
|
||||
uid: access_uid,
|
||||
@@ -52,97 +52,4 @@ class Gitea::Accelerator::MigrateService < ApplicationService
|
||||
def url
|
||||
"/repos/migrate".freeze
|
||||
end
|
||||
|
||||
def post(url, params)
|
||||
puts "[gitea] request params: #{params}"
|
||||
puts "[gitea] access_username: #{access_username}"
|
||||
puts "[gitea] access_password: #{access_password}"
|
||||
conn.post do |req|
|
||||
req.url full_url(url)
|
||||
req.body = params.to_json
|
||||
end
|
||||
end
|
||||
|
||||
def conn
|
||||
@client ||= begin
|
||||
Faraday.new(url: domain) do |req|
|
||||
req.request :url_encoded
|
||||
req.headers['Content-Type'] = 'application/json'
|
||||
req.response :logger # 显示日志
|
||||
req.adapter Faraday.default_adapter
|
||||
req.basic_auth(access_username, access_password)
|
||||
end
|
||||
end
|
||||
@client
|
||||
end
|
||||
|
||||
def base_url
|
||||
accelerator["base_url"]
|
||||
end
|
||||
|
||||
def domain
|
||||
accelerator["domain"]
|
||||
end
|
||||
|
||||
def api_url
|
||||
[domain, base_url].join('')
|
||||
end
|
||||
|
||||
def full_url(api_rest, action='post')
|
||||
url = [api_url, api_rest].join('').freeze
|
||||
url = action === 'get' ? url : URI.escape(url)
|
||||
puts "[gitea] request url: #{url}"
|
||||
url
|
||||
end
|
||||
|
||||
def access_username
|
||||
accelerator["access_key_id"]
|
||||
end
|
||||
|
||||
def access_password
|
||||
accelerator["access_key_secret"]
|
||||
end
|
||||
|
||||
def access_uid
|
||||
accelerator["access_admin_uid"]
|
||||
end
|
||||
|
||||
def accelerator
|
||||
Gitea.gitea_config[:accelerator]
|
||||
end
|
||||
|
||||
def render_status(response)
|
||||
puts "[gitea] response status: #{response.status}"
|
||||
puts "[gitea] response body: #{response.body}"
|
||||
case response.status
|
||||
when 201
|
||||
success
|
||||
when 403
|
||||
error('APIForbiddenError')
|
||||
when 422
|
||||
error('APIValidationError')
|
||||
else
|
||||
error("MigrateError")
|
||||
end
|
||||
end
|
||||
|
||||
def error(message)
|
||||
{
|
||||
status: :error,
|
||||
message: message,
|
||||
data: nil
|
||||
}
|
||||
end
|
||||
|
||||
def success(data=nil)
|
||||
{
|
||||
status: :success,
|
||||
message: nil,
|
||||
data: data
|
||||
}
|
||||
end
|
||||
|
||||
def check_accelerator!
|
||||
accelerator.blank? || access_username.blank? || access_password.blank? || domain.blank?
|
||||
end
|
||||
end
|
||||
31
app/services/gitea/accelerator/sync_mirrored_service.rb
Normal file
31
app/services/gitea/accelerator/sync_mirrored_service.rb
Normal file
@@ -0,0 +1,31 @@
|
||||
# Sync a mirrored repository
|
||||
class Gitea::Accelerator::SyncMirroredService < Gitea::Accelerator::BaseService
|
||||
attr_reader :repo, :token
|
||||
|
||||
# repo *
|
||||
# name of the repo to sync
|
||||
# example:
|
||||
# Gitea::Accelerator::SyncMirroredService.call(repo.identifier)
|
||||
def initialize(repo, token=nil)
|
||||
@repo = repo
|
||||
@token = token
|
||||
end
|
||||
|
||||
def call
|
||||
return error('[gitea:] accelerator config missing') if check_accelerator!
|
||||
|
||||
response = post(url, request_params)
|
||||
|
||||
{status: response.status}
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def request_params
|
||||
Hash.new.merge(token: token).compact
|
||||
end
|
||||
|
||||
def url
|
||||
"/repos/#{access_username}/#{repo}/mirror-sync".freeze
|
||||
end
|
||||
end
|
||||
23
app/services/gitea/user/headmap_service.rb
Normal file
23
app/services/gitea/user/headmap_service.rb
Normal file
@@ -0,0 +1,23 @@
|
||||
class Gitea::User::HeadmapService < Gitea::ClientService
|
||||
attr_reader :start_time, :end_time, :username
|
||||
|
||||
def initialize(username, start_time, end_time)
|
||||
@username = username
|
||||
@start_time = start_time
|
||||
@end_time = end_time
|
||||
end
|
||||
|
||||
def call
|
||||
response = get(url, params)
|
||||
render_response(response)
|
||||
end
|
||||
|
||||
private
|
||||
def params
|
||||
Hash.new.merge(start: start_time, end: end_time)
|
||||
end
|
||||
|
||||
def url
|
||||
"/users/#{username}/heatmap".freeze
|
||||
end
|
||||
end
|
||||
@@ -34,7 +34,7 @@ class Projects::TransferService < ApplicationService
|
||||
def update_visit_teams
|
||||
if new_owner.is_a?(Organization)
|
||||
# 为包含组织所有项目的团队创建项目访问权限
|
||||
new_owner.build_permit_team_projects(project.id)
|
||||
new_owner.build_permit_team_projects!(project.id)
|
||||
else
|
||||
project.team_projects.each(&:destroy!)
|
||||
end
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
json.name issue.try(:subject)
|
||||
json.issue_type issue.issue_type == "1" ? "普通" : "悬赏"
|
||||
json.status_id issue.try(:status_id)
|
||||
json.issue_status issue.issue_status.try(:name)
|
||||
json.priority issue.priority.try(:name)
|
||||
json.priority_id issue.try(:priority_id)
|
||||
json.version issue.version.try(:name)
|
||||
json.created_at format_time(issue.try(:created_on))
|
||||
json.updated_at format_time(issue.try(:updated_on))
|
||||
json.assign_user_name issue&.get_assign_user.try(:show_real_name)
|
||||
|
||||
17
app/views/project_trends/_detail.json.jbuilder
Normal file
17
app/views/project_trends/_detail.json.jbuilder
Normal file
@@ -0,0 +1,17 @@
|
||||
json.id trend.id
|
||||
json.trend_type trend.trend_type
|
||||
json.action_type l("trend.#{trend.action_type}") + l("trend.#{trend.trend_type}")
|
||||
json.trend_id trend.trend_id
|
||||
json.user_name trend.user.try(:show_real_name)
|
||||
json.user_login trend.user.login
|
||||
json.user_avatar url_to_avatar(trend.user)
|
||||
json.action_time time_from_now(trend.created_at)
|
||||
|
||||
if trend.trend_type == "Issue"
|
||||
json.partial! "issues/simple_issue_item", locals: {issue: trend.trend}
|
||||
elsif trend.trend_type == "VersionRelease"
|
||||
json.partial! "version_releases/simple_version_release", locals: {version: trend.trend}
|
||||
else
|
||||
json.name trend.trend&.title
|
||||
json.created_at format_time(trend.trend&.created_at)
|
||||
end
|
||||
@@ -9,25 +9,9 @@ json.limit @limit
|
||||
json.project_trends_size @project_trends_size
|
||||
json.project_trends do
|
||||
json.array! @project_trends.to_a.each do |trend|
|
||||
json.id trend.id
|
||||
json.trend_type trend.trend_type
|
||||
json.action_type l("trend.#{trend.action_type}") + l("trend.#{trend.trend_type}")
|
||||
json.trend_id trend.trend_id
|
||||
json.user_name trend.user.try(:show_real_name)
|
||||
json.user_login trend.user.login
|
||||
json.user_avatar url_to_avatar(trend.user)
|
||||
|
||||
if trend.trend_type == "Issue"
|
||||
json.partial! "issues/simple_issue_item", locals: {issue: trend.trend}
|
||||
elsif trend.trend_type == "VersionRelease"
|
||||
json.partial! "version_releases/simple_version_release", locals: {version: trend.trend}
|
||||
else
|
||||
json.name trend.trend.title
|
||||
json.created_at format_time(trend.trend.created_at)
|
||||
end
|
||||
|
||||
|
||||
#后续需要天际pullrequest 和 版本的内容
|
||||
|
||||
json.partial! "detail", trend: trend
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -5,6 +5,9 @@ json.name project.name
|
||||
json.description Nokogiri::HTML(project.description).text
|
||||
json.visits project.visits
|
||||
json.praises_count project.praises_count.to_i
|
||||
json.watchers_count project.watchers_count.to_i
|
||||
json.issues_count project.issues_count.to_i
|
||||
json.pull_requests_count project.pull_requests_count.to_i
|
||||
json.forked_count project.forked_count.to_i
|
||||
json.is_public project.is_public
|
||||
json.mirror_url project.repository&.mirror_url
|
||||
@@ -14,6 +17,7 @@ json.time_ago time_from_now(project.updated_on)
|
||||
json.forked_from_project_id project.forked_from_project_id
|
||||
json.open_devops project.open_devops?
|
||||
json.platform project.platform
|
||||
json.is_pinned project.has_pinned_users.include?(current_user)
|
||||
json.author do
|
||||
if project.educoder?
|
||||
project_educoder = project.project_educoder
|
||||
|
||||
@@ -48,7 +48,7 @@ if @result[:repo]
|
||||
json.size replace_bytes_to_b(number_to_human_size(@result[:repo]['size'].to_i*1024))
|
||||
json.ssh_url @result[:repo]['ssh_url']
|
||||
json.clone_url @result[:repo]['clone_url']
|
||||
json.default_branch @result[:repo]['default_branch']
|
||||
json.default_branch @project.educoder? ? "master" : @result[:repo]['default_branch']
|
||||
json.empty @result[:repo]['empty']
|
||||
json.full_name @result[:repo]['full_name']
|
||||
json.private @result[:repo]['private']
|
||||
|
||||
@@ -12,4 +12,5 @@ json.permission render_permission(current_user, @project)
|
||||
json.is_transfering @project.is_transfering
|
||||
json.transfer do
|
||||
json.partial! "/users/user_simple", locals: {user: @project&.applied_transfer_project&.owner}
|
||||
end
|
||||
end
|
||||
json.is_pinned @project.has_pinned_users.include?(current_user)
|
||||
@@ -1,7 +1,20 @@
|
||||
json.user_id user.id
|
||||
json.login user.login
|
||||
json.name user.full_name
|
||||
json.username @user.full_name
|
||||
json.real_name @user.real_name
|
||||
json.grade user.grade
|
||||
json.identity user&.user_extension&.identity
|
||||
# json.email user.mail # 邮箱原则上不暴露的,如果实在需要的话只能对某些具体的接口公开
|
||||
json.image_url url_to_avatar(user)
|
||||
json.gender @user.gender
|
||||
json.login @user.login
|
||||
json.user_id @user.id
|
||||
json.image_url url_to_avatar(@user)
|
||||
json.admin @user.admin?
|
||||
json.user_identity @user.identity
|
||||
json.is_watch current_user&.watched?(@user)
|
||||
json.watched_count @user.fan_count #粉丝
|
||||
json.watching_count @user.follow_count #关注数
|
||||
json.created_time format_time(@user.created_on)
|
||||
json.email @user.show_email ? @user.mail : nil
|
||||
json.province @user.show_location ? @user.province : nil
|
||||
json.city @user.show_location ? @user.city : nil
|
||||
json.custom_department @user.show_department ? @user.custom_department : nil
|
||||
json.description @user.description
|
||||
@@ -3,7 +3,7 @@ json.format_time target.created_at.strftime("%Y-%m-%d")
|
||||
json.name user.try(:show_real_name)
|
||||
json.login user.try(:login)
|
||||
json.image_url url_to_avatar(user)
|
||||
json.is_current_user current_user.try(:id) == target.user_id
|
||||
json.is_current_user current_user.try(:id) == user.id
|
||||
json.is_watch current_user&.watched?(user)
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
json.username @user.full_name
|
||||
json.real_name @user.real_name
|
||||
json.gender @user.gender
|
||||
json.login @user.login
|
||||
json.user_id @user.id
|
||||
json.image_url url_to_avatar(@user)
|
||||
@@ -14,3 +15,9 @@ json.profile_completed @user.profile_completed?
|
||||
json.professional_certification @user.professional_certification
|
||||
json.devops_step @user.devops_step
|
||||
json.ci_certification @user.ci_certification?
|
||||
json.email @user.mail
|
||||
json.province @user.province
|
||||
json.city @user.city
|
||||
json.custom_department @user.custom_department
|
||||
json.description @user.description
|
||||
json.(@user, :show_email, :show_department, :show_location)
|
||||
5
app/views/users/headmaps/index.json.jbuilder
Normal file
5
app/views/users/headmaps/index.json.jbuilder
Normal file
@@ -0,0 +1,5 @@
|
||||
json.total_contributions @headmaps.collect{|map| map["contributions"]}.reduce(0, :+)
|
||||
json.headmaps @headmaps.each do |map|
|
||||
json.date Time.at(map["timestamp"].to_i).strftime("%Y-%m-%d")
|
||||
json.contributions map["contributions"]
|
||||
end
|
||||
7
app/views/users/is_pinned_projects/index.json.jbuilder
Normal file
7
app/views/users/is_pinned_projects/index.json.jbuilder
Normal file
@@ -0,0 +1,7 @@
|
||||
json.total_count @is_pinned_projects.total_count
|
||||
json.projects @is_pinned_projects.each do |project|
|
||||
json.partial! "projects/project_detail", project: project&.project
|
||||
json.id project.id
|
||||
json.position project.position
|
||||
json.project_id project.project_id
|
||||
end
|
||||
4
app/views/users/project_trends/index.json.jbuilder
Normal file
4
app/views/users/project_trends/index.json.jbuilder
Normal file
@@ -0,0 +1,4 @@
|
||||
json.total_count @project_trends.total_count
|
||||
json.project_trends @project_trends.each do |trend|
|
||||
json.partial! "project_trends/detail", trend: trend
|
||||
end
|
||||
@@ -1,15 +1,4 @@
|
||||
# json.partial! 'users/user', locals: { user: @user }
|
||||
|
||||
json.username @user.full_name
|
||||
json.real_name @user.real_name
|
||||
json.login @user.login
|
||||
json.user_id @user.id
|
||||
json.image_url url_to_avatar(@user)
|
||||
json.admin @user.admin?
|
||||
json.user_identity @user.identity
|
||||
json.is_watch current_user&.watched?(@user)
|
||||
json.watched_count @user.fan_count #粉丝
|
||||
json.watching_count @user.follow_count #关注数
|
||||
json.partial! 'users/user', locals: { user: @user }
|
||||
json.undo_messages @waiting_applied_messages.size
|
||||
json.undo_transfer_projects @common_applied_transfer_projects.size
|
||||
json.undo_events @undo_events
|
||||
@@ -17,4 +6,10 @@ json.user_composes_count @user_composes_count
|
||||
json.user_org_count @user_org_count
|
||||
json.common_projects_count @projects_common_count
|
||||
json.mirror_projects_count @projects_mirrior_count
|
||||
json.sync_mirror_projects_count @projects_sync_mirrior_count
|
||||
json.sync_mirror_projects_count @projects_sync_mirrior_count
|
||||
json.created_time format_time(@user.created_on)
|
||||
json.email @user.show_email ? @user.mail : nil
|
||||
json.province @user.show_location ? @user.province : nil
|
||||
json.city @user.show_location ? @user.city : nil
|
||||
json.custom_department @user.show_department ? @user.custom_department : nil
|
||||
json.description @user.description
|
||||
19
app/views/users/statistics/develop.json.jbuilder
Normal file
19
app/views/users/statistics/develop.json.jbuilder
Normal file
@@ -0,0 +1,19 @@
|
||||
json.platform do
|
||||
json.influence @platform_influence
|
||||
json.contribution @platform_contribution
|
||||
json.activity @platform_activity
|
||||
json.experience @platform_experience
|
||||
json.language @platform_language
|
||||
# json.languages_percent @platform_languages_percent
|
||||
# json.each_language_score @platform_each_language_score
|
||||
end
|
||||
|
||||
json.user do
|
||||
json.influence @influence
|
||||
json.contribution @contribution
|
||||
json.activity @activity
|
||||
json.experience @experience
|
||||
json.language @language
|
||||
json.languages_percent @languages_percent
|
||||
json.each_language_score @each_language_score
|
||||
end
|
||||
19
app/views/users/statistics/role.json.jbuilder
Normal file
19
app/views/users/statistics/role.json.jbuilder
Normal file
@@ -0,0 +1,19 @@
|
||||
json.total_projects_count @full_member_projects_count
|
||||
json.role do
|
||||
json.owner do
|
||||
json.count @owner_projects_count
|
||||
json.percent (@owner_projects_count.to_f/@full_member_projects_count).round(2)
|
||||
end
|
||||
json.manager do
|
||||
json.count @manager_projects_count
|
||||
json.percent (@manager_projects_count.to_f/@full_member_projects_count).round(2)
|
||||
end
|
||||
json.developer do
|
||||
json.count @developer_projects_count
|
||||
json.percent (@developer_projects_count.to_f/@full_member_projects_count).round(2)
|
||||
end
|
||||
json.reporter do
|
||||
json.count @reporter_projects_count
|
||||
json.percent (@reporter_projects_count.to_f/@full_member_projects_count).round(2)
|
||||
end
|
||||
end
|
||||
1
app/views/users/update.json.jbuilder
Normal file
1
app/views/users/update.json.jbuilder
Normal file
@@ -0,0 +1 @@
|
||||
json.partial! 'users/user', locals: { user: @user }
|
||||
@@ -1,7 +1,7 @@
|
||||
json.count @watchers_count
|
||||
json.users do
|
||||
json.array! @watchers do |watcher|
|
||||
json.partial! "/users/watch_user_detail", locals: {target: watcher, user: watcher.watchable}
|
||||
json.partial! "/users/watch_user_detail", target: watcher, user: watcher.watchable
|
||||
end
|
||||
# json.partial! "/users/watch_user_detail", collection: @watchers, as: :target
|
||||
end
|
||||
Reference in New Issue
Block a user