diff --git a/app/controllers/accounts_controller.rb b/app/controllers/accounts_controller.rb index 292adad6..f09eb14a 100644 --- a/app/controllers/accounts_controller.rb +++ b/app/controllers/accounts_controller.rb @@ -125,25 +125,21 @@ class AccountsController < ApplicationController # gitea用户注册, email, username, password - # interactor = Gitea::RegisterInteractor.call({username: user.login, email: user.mail, password: password}) - # if interactor.success? - # gitea_user = interactor.result - # result = Gitea::User::GenerateTokenService.call(user.login, password) - # user.gitea_token = result['sha1'] - # user.gitea_uid = gitea_user[:body]['id'] - # if user.save! - # UserExtension.create!(user_id: user.id) - # successful_authentication(user) - # render_ok - # end - # else - # tip_exception(-1, interactor.error) - # end - if user.save! - UserExtension.create!(user_id: user.id) - successful_authentication(user) - render_ok + interactor = Gitea::RegisterInteractor.call({username: user.login, email: user.mail, password: password}) + if interactor.success? + gitea_user = interactor.result + result = Gitea::User::GenerateTokenService.call(user.login, password) + user.gitea_token = result['sha1'] + user.gitea_uid = gitea_user[:body]['id'] + if user.save! + UserExtension.create!(user_id: user.id) + successful_authentication(user) + render_ok + end + else + tip_exception(-1, interactor.error) end + rescue Register::BaseForm::EmailError => e render_error(-2, e.message) rescue Register::BaseForm::LoginError => e diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index d7707391..c9a75e96 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -265,9 +265,9 @@ class ApplicationController < ActionController::Base end end - # if !User.current.logged? && Rails.env.development? - # User.current = User.find 1 - # end + if !User.current.logged? && Rails.env.development? + User.current = User.find 104 + end # 测试版前端需求 diff --git a/app/controllers/organizations/projects_controller.rb b/app/controllers/organizations/projects_controller.rb index b36a7612..ea47cc09 100644 --- a/app/controllers/organizations/projects_controller.rb +++ b/app/controllers/organizations/projects_controller.rb @@ -14,6 +14,22 @@ class Organizations::ProjectsController < Organizations::BaseController @projects = paginate(@projects) end + #######################change################################# + def organizationBadge + watchers_count = @organization.watchers_count + + @watchered = judge_level(watchers_count, 10, 20, 100) + + @badge = organizationBadge.find_or_create_by(organization_id: @organization.id) + + if @watchered != @badge.watched + @badge.watched = @watchered + @badge.save + end + render :json => {list: [{watchered: @watchered}], count: 1} + end + #######################change################################# + def search tip_exception("请输入搜索关键词") if params[:search].nil? public_projects_sql = @organization.projects.where(is_public: true).to_sql @@ -42,4 +58,17 @@ class Organizations::ProjectsController < Organizations::BaseController def sort_direction %w(desc asc).include?(params[:sort_direction]) ? params[:sort_direction] : 'desc' end + + + def judge_level(judged, low, mid, high) + if judged < low + return 0 + elsif judged < mid + return 1 + elsif judged < high + return 2 + else + return 3 + end + end end \ No newline at end of file diff --git a/app/controllers/organizations/team_projects_controller.rb b/app/controllers/organizations/team_projects_controller.rb index 2badca17..76707862 100644 --- a/app/controllers/organizations/team_projects_controller.rb +++ b/app/controllers/organizations/team_projects_controller.rb @@ -6,7 +6,6 @@ class Organizations::TeamProjectsController < Organizations::BaseController def index @team_projects = @team.team_projects - @team_projects = paginate(@team_projects) end diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb index b41dd170..4b2f1e78 100644 --- a/app/controllers/repositories_controller.rb +++ b/app/controllers/repositories_controller.rb @@ -12,6 +12,7 @@ class RepositoriesController < ApplicationController before_action :get_ref, only: %i[entries sub_entries top_counts file archive] before_action :get_latest_commit, only: %i[entries sub_entries top_counts] before_action :get_statistics, only: %i[top_counts] + before_action :preload_badge, only: [:badges] def files result = @project.educoder? ? nil : Gitea::Repository::Files::GetService.call(@owner, @project.identifier, @ref, params[:search], @owner.gitea_token) @@ -20,18 +21,49 @@ class RepositoriesController < ApplicationController def preload_badge - + @praised_cache = "praised" + @forked_cache = "forked" + @watchered_cache = "watchered" + @badge = RepositoryBadge.find_or_create_by(user_id: observed_user.id) + $redis_cache.hset(project_statistic_key, @many_projects_cache, @badge.many_projects) + $redis_cache.hset(project_statistic_key, @manyParisesProject_cache, @badge.manyParisesProject) + $redis_cache.hset(project_statistic_key, @parises_project_cache, @badge.parises_project) end + ####################change for repository############################ + + def badges - @badge = RepositoryBadge.where(project_id: @project.id).pluck(:popular_project, :recommend_project, :many_stars).first - popular_project = @badge[0] - recommend_project = @badge[1] - many_stars = @badge[2] - render :json => {popular_project: popular_project, recommend_project: recommend_project, many_stars: many_stars} + preload_badge + @badges_dic = Hash.new(0) + praises_count = @project.praises_count.to_i + forked_count = @project.forked_count.to_i + watchers_count = @project.watchers_count.to_i + @praised = judge_level(praises_count, 10, 20,100) + redis_judge_reload @praised_cache, @praised + @badges_dic["praised_cache"] = $redis_cache.hget(project_statistic_key, @praised_cache).to_i + + @forked = judge_level(forked_count, 5, 10,100) + redis_judge_reload @forked_cache, @forked + @badges_dic["forked_cache"] = $redis_cache.hget(project_statistic_key, @forked_cache).to_i + + @watchered = judge_level(watchers_count, 10, 20,100) + redis_judge_reload @watchered_cache, @watchered + @badges_dic["forked_cache"] = $redis_cache.hget(project_statistic_key, @forked_cache).to_i + + + badges_visable = Array.new + @badges_dic.each do |key,value| + if value > 0 + badges_visable.append({"#{key}":value}) + end + end + render :json => {list: badges_visable, count: badges_visable.size} end + ########################################################## + # 新版项目详情 def detail @user = current_user @@ -369,4 +401,37 @@ class RepositoriesController < ApplicationController end end + + def judge_level(judged, low, mid, high) + if judged < low + return 0 + elsif judged < mid + return 1 + elsif judged < high + return 2 + else + return 3 + end + end + + def redis_judge_reload(judge_cache, new_value) + if $redis_cache.hget(project_statistic_key, judge_cache).to_i != new_value + $redis_cache.del(project_statistic_key) + updateService judge_cache, new_value + load_redis + end + end + + def project_statistic_key + "project:#{@project.id}" + end + + def updateService(update_name, update_value) + @badge = RepositoryBadge.find_or_create_by(user_id: observed_user.id) + @badge.update_attribute(update_name,update_value) + @badge.save + end + + + end diff --git a/app/controllers/users/statistics_controller.rb b/app/controllers/users/statistics_controller.rb index 22e7dcba..680fb49f 100644 --- a/app/controllers/users/statistics_controller.rb +++ b/app/controllers/users/statistics_controller.rb @@ -22,14 +22,33 @@ class Users::StatisticsController < Users::BaseController end ###############change############### - # badges 接口 url 路径为/api/users/:user_id/statistic/badges + # 用户badges 接口 url 路径为/api/users/:user_id/statistic/badges + + # 三类 + # 第一类 贡献类 + # 1. 用户累积获得高星 + # 2. 用户关注数超过10人 + # 3. 用户的累积获赞人数 + # 4. 用户连续一周有commit + # 5. 用户累积pr数 + + # 第二类 活动类 + # 第三类 特殊类 def badges - @badge = Badge.where(user_id: observed_user.id).pluck(:watcher, :pullrequest, :many_fans, :amazing_project_owner).first - watcher = @badge[0] - pullrequest = @badge[1] - many_fans = @badge[2] - amazing_project_owner = @badge[3] - render :json => {watcher: watcher, pullrequest: pullrequest, many_fans: many_fans, amazing_project_owner: amazing_project_owner} + badges_visable = Array.new + @badges_dic.each do |key,value| + if value > 0 + badges_visable.append({"#{key}":value}) + end + end + render :json => {list: badges_visable, count: badges_visable.size} + + # @badge = Badge.where(user_id: observed_user.id).pluck(:watcher, :pullrequest, :many_fans, :amazing_project_owner).first + # watcher = @badge[0] + # pullrequest = @badge[1] + # many_fans = @badge[2] + # amazing_project_owner = @badge[3] + # render :json => {watcher: watcher, pullrequest: pullrequest, many_fans: many_fans, amazing_project_owner: amazing_project_owner} end ###############change############### @@ -235,43 +254,189 @@ class Users::StatisticsController < Users::BaseController end +def count_filter(collection, count_field, countf) + return collection.where("#{count_field} >= ?", countf) +end + +# 判断是否拥有 +def judge_have(judged, count) + return judged >= count ? 1 : 0 +end + +# 判断等级 +def judge_level(judged, low, mid, high) + if judged < low + return 0 + elsif judged < mid + return 1 + elsif judged < high + return 2 + else + return 3 + end +end + +###############change############### +# 用户badges 接口 url 路径为/api/users/:user_id/statistic/badges + +# 三类 +# 第一类 贡献类 +# 1. 用户拥有10个项目以上 +# 2.用户有项目获得高星 +# 3.用户有数个高星项目 +# 4.用户拥有一个点赞数很高的项目 +# 5.用户拥有数个点赞数很高的项目 +# 6. 用户关注数超过10人 +# 7. 用户的累积获赞人数 +# 8. 用户连续一周/月有commit +# 9. 用户累积pr数 + +# 第二类 活动类 +# 第三类 特殊类 + + + def preload_badge_data - #从缓存中读取 - @user_result = Cache::V2::UserStatisticService.new(observed_user.id).read - # 用户被follow数量 - @follow_count = @user_result["follow-count"].to_i - # 用户pr数量 - @pullrequest_count = @user_result["pullrequest-count"].to_i - # 用户issue数量 - @issues_count = @user_result["issue-count"].to_i - # 用户总项目数 - @project_count = @user_result["project-count"].to_i - # 用户项目被fork数量 - @fork_count = @user_result["fork-count"].to_i - # 用户项目关注数 - @project_watchers_count = @user_result["project-watcher-count"].to_i - # 用户项目点赞数 - @project_praises_count = @user_result["project-praise-count"].to_i - # 用户不同语言项目数量 - @project_languages_count = JSON.parse(@user_result["project-language"]) + @many_projects_cache = "many_projects" + @manyParisesProject_cache = "manyParisesProject" + @parises_project_cache = "parises_project" + @manyWatchersProject_cache = "manyWatchersProject" + @watchers_project_cache = "watchers_project" + @many_fans_cache = "many_fans" + @many_pr_cache = "many_pr" + @many_issue_cache = "many_issue" + @active_in_week_cache = "active_in_week" + #加载缓存资源 + load_redis - @stars_stuck = @follow_count >= 16 ? true : false - @pr_stuck = @pullrequest_count >= 5 ? true : false - @many_fans = @fork_count >= 10 ? true : false - @amazing_project_owner = @project_praises_count >= 20 ? true : false + #存放用户获得的徽章字典 + @badges_dic = Hash.new(0) + # 有些数据直接从缓存中读取,由于题目要求不能破坏原本的函数,其他暂时缓存写到了 Cache::V2::UserBadgeService里, + # 但数据类型比较相似,感觉写到UserStatisticService里比较合适,这里暂时使用的是直接查询得到的数据 + @user_result = Cache::V2::UserStatisticService.new(observed_user.id).read + + # 用户项目获得的徽章 + + #用户语言数量 y + + # 用户项目数量 y + project_count = @user_result["project-count"].to_i + @badges_dic["project_count"] = project_count + # 用户点赞数量 y + + # 用户项目被follow数量 + praises_project_count = count_filter(Project.where(user_id:observed_user.id), 'praises_count' , 10).count + praises_project = Project.where(user_id:observed_user.id).maximum('praises_count') + watchers_project_count = count_filter(Project.where(user_id:observed_user.id), 'watchers_count' , 10).count + watchers_project = Project.where(user_id:observed_user.id).maximum('watchers_count') + + # 项目数 + @many_projects = judge_have(project_count, 5) + redis_judge_reload @many_projects_cache, @many_projects + @badges_dic["many_projects"] = $redis_cache.hget(user_statistic_key, @many_projects_cache).to_i - updateService @stars_stuck ,@pr_stuck, @many_fans, @amazing_project_owner + # 用户有超过五个以上的高点赞项目 + @manyParisesProject = judge_have(praises_project_count, 5) + redis_judge_reload @manyParisesProject_cache, @manyParisesProject + @badges_dic["manyParisesProject"] = $redis_cache.hget(user_statistic_key, @manyParisesProject_cache).to_i + #用户有一个点赞数很高的项目 金/银/铜 + @parises_project = judge_level(praises_project, 3, 5, 10) + redis_judge_reload @many_projects_cache, @parises_project + @badges_dic["parises_project"] = $redis_cache.hget(user_statistic_key, @parises_project_cache).to_i + + # 用户有超过五个以上的高关注项目 + @manyWatchersProject = judge_have(watchers_project_count, 5) + redis_judge_reload @manyWatchersProject_cache, @manyWatchersProject + @badges_dic["manyWatchersProject"] = $redis_cache.hget(user_statistic_key, @manyWatchersProject_cache).to_i + + #用户有一个关注数很高的项目 金/银/铜 + @watchers_project = judge_level(watchers_project, 3, 5, 10) + redis_judge_reload @watchers_project_cache, @watchers_project + @badges_dic["watchers_project"] = $redis_cache.hget(user_statistic_key, @watchers_project_cache).to_i + + + + # 用户被follow数量 y + fans = Watcher.where(watchable: observed_user).count + # 用户pr数量 y + pr = PullRequest.where(user_id: observed_user.id).count + # 用户issue数量 y + issue = Issue.where(author_id: observed_user.id).count + + #用户有关注数很多 金/银/铜 + @many_fans = judge_level(fans, 5, 50, 100) + redis_judge_reload @many_fans_cache, @many_fans + @badges_dic["many_fans"] = $redis_cache.hget(user_statistic_key, @many_fans_cache).to_i + + #用户pr很多 金/银/铜 + @many_pr = judge_level(pr, 5, 50, 100) + redis_judge_reload @many_pr_cache, @many_pr + @badges_dic["many_pr"] = $redis_cache.hget(user_statistic_key, @many_pr_cache).to_i + + #用户issue很多 金/银/铜 + @many_issue = judge_level(issue, 5, 50, 100) + redis_judge_reload @many_issue_cache, @many_issue + @badges_dic["many_issue"] = $redis_cache.hget(user_statistic_key, @many_issue_cache).to_i + + #一周内活跃 + 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] + active_commit = commit_data.select{|item| item["contributions"] >= 1}.size + @active_in_week = active_commit == 7 ? 1 : 0 + + @badges_dic["active_in_week"] = $redis_cache.hget(user_statistic_key, @active_in_week_cache).to_i + + #TODO fans_raise_quickly end -def updateService(stars_stuck, pr_stuck, many_fans, amazing_project_owner) + + +def user_statistic_key + "user:#{@user_id}" +end + +def redis_judge_reload(judge_cache, new_value) + if $redis_cache.hget(user_statistic_key, judge_cache).to_i != new_value + $redis_cache.del(user_statistic_key) + updateService judge_cache, new_value + load_redis + end +end + + +def cache_name + @many_projects_cache = "many_projects" + @manyParisesProject_cache = "manyParisesProject" + @parises_project_cache = "parises_project" + @manyWatchersProject_cache = "manyWatchersProject" + @watchers_project_cache = "watchers_project" + @many_fans_cache = "many_fans" + @many_pr_cache = "many_pr" + @many_issue_cache = "many_issue" + @active_in_week_cache = "active_in_week" +end + + +def load_redis @badge = Badge.find_or_create_by(user_id: observed_user.id) - @badge.watcher = stars_stuck - @badge.pullrequest = pr_stuck - @badge.many_fans = many_fans - @badge.amazing_project_owner = amazing_project_owner + $redis_cache.hset(user_statistic_key, @many_projects_cache, @badge.many_projects) + $redis_cache.hset(user_statistic_key, @manyParisesProject_cache, @badge.manyParisesProject) + $redis_cache.hset(user_statistic_key, @parises_project_cache, @badge.parises_project) + $redis_cache.hset(user_statistic_key, @manyWatchersProject_cache, @badge.manyWatchersProject) + $redis_cache.hset(user_statistic_key, @watchers_project_cache, @badge.watchers_project) + $redis_cache.hset(user_statistic_key, @many_fans_cache, @badge.many_fans) + $redis_cache.hset(user_statistic_key, @many_pr_cache, @badge.many_pr) + $redis_cache.hset(user_statistic_key, @many_issue_cache, @badge.many_issue) + $redis_cache.hset(user_statistic_key, @active_in_week_cache, @badge.active_in_week) +end + +def updateService(update_name, update_value) + @badge = Badge.find_or_create_by(user_id: observed_user.id) + @badge.update_attribute(update_name,update_value) @badge.save -end \ No newline at end of file +end + diff --git a/app/models/badge.rb b/app/models/badge.rb index 661f69ce..3fba683e 100644 --- a/app/models/badge.rb +++ b/app/models/badge.rb @@ -2,14 +2,19 @@ # # Table name: badges # -# id :integer not null, primary key -# user_id :integer -# watcher :boolean default("0") -# pullrequest :boolean default("0") -# many_fans :boolean default("0") -# amazing_project_owner :boolean default("0") -# created_at :datetime not null -# updated_at :datetime not null +# id :integer not null, primary key +# user_id :integer +# created_at :datetime not null +# updated_at :datetime not null +# many_projects :integer default("0") +# manyParisesProject :integer default("0") +# parises_project :integer default("0") +# manyWatchersProject :integer default("0") +# watchers_project :integer default("0") +# many_fans :integer default("0") +# many_pr :integer default("0") +# many_issue :integer default("0") +# active_in_week :integer default("0") # class Badge < ApplicationRecord diff --git a/app/models/organization_badge.rb b/app/models/organization_badge.rb new file mode 100644 index 00000000..2ecc2acb --- /dev/null +++ b/app/models/organization_badge.rb @@ -0,0 +1,2 @@ +class OrganizationBadge < ApplicationRecord +end diff --git a/app/models/repository_badge.rb b/app/models/repository_badge.rb index 90529aee..c2881e8e 100644 --- a/app/models/repository_badge.rb +++ b/app/models/repository_badge.rb @@ -1,2 +1,15 @@ +# == Schema Information +# +# Table name: repository_badges +# +# id :integer not null, primary key +# project_id :integer +# popular_project :integer default("0") +# recommend_project :integer default("0") +# many_stars :integer default("0") +# created_at :datetime not null +# updated_at :datetime not null +# + class RepositoryBadge < ApplicationRecord end diff --git a/config/routes.rb b/config/routes.rb index 2a14b818..9f216ca5 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -304,7 +304,7 @@ Rails.application.routes.draw do end resources :project_trends, only: [:index] resources :organizations, only: [:index] - # resources :projects, only: [:index] + resources :projects, only: [:index] # resources :subjects, only: [:index] resources :project_packages, only: [:index] # 私信 @@ -442,6 +442,7 @@ Rails.application.routes.draw do get :files get :detail get :entries + get :badges match :sub_entries, :via => [:get, :put] get :commits get :commits_slice diff --git a/db/migrate/20230922081420_change_for_badges.rb b/db/migrate/20230922081420_change_for_badges.rb new file mode 100644 index 00000000..59a489c7 --- /dev/null +++ b/db/migrate/20230922081420_change_for_badges.rb @@ -0,0 +1,13 @@ +class ChangeForBadges < ActiveRecord::Migration[5.2] + def change + add_column :badges, :many_projects, :integer ,default: 0 + add_column :badges, :manyParisesProject ,:integer ,default: 0 + add_column :badges, :parises_project ,:integer ,default: 0 + add_column :badges, :manyWatchersProject,:integer ,default: 0 + add_column :badges, :watchers_project,:integer ,default: 0 + add_column :badges, :many_fans,:integer ,default: 0 + add_column :badges, :many_pr,:integer ,default: 0 + add_column :badges, :many_issue,:integer ,default: 0 + add_column :badges, :active_in_week,:integer ,default: 0 + end +end diff --git a/db/migrate/20230922082645_addcoloum_for_badges.rb b/db/migrate/20230922082645_addcoloum_for_badges.rb new file mode 100644 index 00000000..c42f8cd8 --- /dev/null +++ b/db/migrate/20230922082645_addcoloum_for_badges.rb @@ -0,0 +1,13 @@ +class AddcoloumForBadges < ActiveRecord::Migration[5.2] + def change + add_column :badges, :many_projects, :integer ,default: 0 + add_column :badges, :manyParisesProject ,:integer ,default: 0 + add_column :badges, :parises_project ,:integer ,default: 0 + add_column :badges, :manyWatchersProject,:integer ,default: 0 + add_column :badges, :watchers_project,:integer ,default: 0 + add_column :badges, :many_fans,:integer ,default: 0 + add_column :badges, :many_pr,:integer ,default: 0 + add_column :badges, :many_issue,:integer ,default: 0 + add_column :badges, :active_in_week,:integer ,default: 0 + end +end diff --git a/db/migrate/20230922125304_create_organization_badges.rb b/db/migrate/20230922125304_create_organization_badges.rb new file mode 100644 index 00000000..dd9bf9c6 --- /dev/null +++ b/db/migrate/20230922125304_create_organization_badges.rb @@ -0,0 +1,8 @@ +class CreateOrganizationBadges < ActiveRecord::Migration[5.2] + def change + create_table :organization_badges do |t| + + t.timestamps + end + end +end