diff --git a/CHANGELOG.md b/CHANGELOG.md
index d24953c43..a5250040e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,21 @@
# Changelog
+## [v3.1.0](https://forgeplus.trustie.net/projects/jasder/forgeplus/releases) - 2021-06-09
+
+* ENHANCEMENTS
+ * ADD 用户活动统计图表功能
+ * ADD 用户精选项目功能
+ * ADD 用户贡献度统计图表功能
+ * ADD 用户开发能力数据统计工
+ * ADD 用户角色定位展示功能
+ * ADD 用户专业定位标签展示功能
+ * ADD 修改用户基本资料功能
+ * ADD 更改密码功能
+ * ADD 用户个人主页基本现在展示可配置功能
+
+* BUGFIXES
+ * Fix 解决一些bug
+ * Fix 优化美化页面
-## [v3.0.4](https://forgeplus.trustie.net/projects/jasder/forgeplus/releases) - 2021-05-24
* BUGFIXES
* Fix 在线修改文件,页面文件显不及时的问题(46049)
diff --git a/app/controllers/admins/auth_schools_controller.rb b/app/controllers/admins/auth_schools_controller.rb
index 825c04cdc..39d5b9683 100644
--- a/app/controllers/admins/auth_schools_controller.rb
+++ b/app/controllers/admins/auth_schools_controller.rb
@@ -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_WS(lastname, firstname, nickname) like ?", "%#{params[:name].strip.to_s}%").limit(10)
+ @users = User.where.not(id: user_ids).where("CONCAT(lastname, firstname) like ? OR nickname like ?", "%#{params[:name].strip.to_s}%", "%#{params[:name].strip.to_s}%").limit(10)
end
# 添加认证学校管理员
diff --git a/app/controllers/admins/faqs_controller.rb b/app/controllers/admins/faqs_controller.rb
index fc00f847c..250d3d60a 100644
--- a/app/controllers/admins/faqs_controller.rb
+++ b/app/controllers/admins/faqs_controller.rb
@@ -2,8 +2,8 @@ class Admins::FaqsController < Admins::BaseController
before_action :find_faq, only: [:edit,:update, :destroy]
def index
- sort_by = params[:sort_by] ||= 'updated_at'
- sort_direction = params[:sort_direction] ||= 'desc'
+ sort_by = Faq.column_names.include?(params[:sort_by]) ? params[:sort_by] : 'updated_at'
+ sort_direction = %w(desc asc).include?(params[:sort_direction]) ? params[:sort_direction] : 'desc'
keyword = params[:keyword].to_s.strip
collection = Faq.search_question(keyword).order("#{sort_by} #{sort_direction}")
diff --git a/app/controllers/admins/laboratories_controller.rb b/app/controllers/admins/laboratories_controller.rb
index 46463fed0..7044b6218 100644
--- a/app/controllers/admins/laboratories_controller.rb
+++ b/app/controllers/admins/laboratories_controller.rb
@@ -32,8 +32,8 @@ class Admins::LaboratoriesController < Admins::BaseController
keyword = params[:keyword].to_s.strip
if keyword.present?
- like_sql = 'shixuns.name LIKE :keyword OR CONCAT_WS(users.lastname, users.firstname, users.nickname) LIKE :keyword '\
- 'OR mirror_repositories.name LIKE :keyword'
+ like_sql = 'shixuns.name LIKE :keyword OR CONCAT(users.lastname, users.firstname) LIKE :keyword '\
+ '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_WS(users.lastname, users.firstname, users.nickname) LIKE :keyword'
+ like_sql = 'subjects.name LIKE :keyword OR CONCAT(users.lastname, users.firstname) LIKE :keyword OR users.nickname LIKE :keyword'
subjects = subjects.joins(:user).where(like_sql, keyword: "%#{keyword}%")
end
diff --git a/app/controllers/admins/project_categories_controller.rb b/app/controllers/admins/project_categories_controller.rb
index 944a2cf04..ba83e841d 100644
--- a/app/controllers/admins/project_categories_controller.rb
+++ b/app/controllers/admins/project_categories_controller.rb
@@ -3,8 +3,8 @@ class Admins::ProjectCategoriesController < Admins::BaseController
before_action :validate_names, only: [:create, :update]
def index
- sort_by = params[:sort_by] ||= 'created_at'
- sort_direction = params[:sort_direction] ||= 'desc'
+ sort_by = ProjectCategory.column_names.include?(params[:sort_by]) ? params[:sort_by] : 'created_at'
+ sort_direction = %w(desc asc).include?(params[:sort_direction]) ? params[:sort_direction] : 'desc'
q = ProjectCategory.ransack(name_cont: params[:name])
project_categories = q.result(distinct: true).order("#{sort_by} #{sort_direction}")
@project_categories = paginate(project_categories)
diff --git a/app/controllers/admins/project_ignores_controller.rb b/app/controllers/admins/project_ignores_controller.rb
index 427ee86b8..360f189c0 100644
--- a/app/controllers/admins/project_ignores_controller.rb
+++ b/app/controllers/admins/project_ignores_controller.rb
@@ -3,8 +3,8 @@ class Admins::ProjectIgnoresController < Admins::BaseController
before_action :validate_params, only: [:create, :update]
def index
- sort_by = params[:sort_by] ||= 'created_at'
- sort_direction = params[:sort_direction] ||= 'desc'
+ sort_by = Ignore.column_names.include?(params[:sort_by]) ? params[:sort_by] : 'created_at'
+ sort_direction = %w(desc asc).include?(params[:sort_direction]) ? params[:sort_direction] : 'desc'
q = Ignore.ransack(name_cont: params[:search])
project_ignores = q.result(distinct: true).order("#{sort_by} #{sort_direction}")
@project_ignores = paginate(project_ignores)
diff --git a/app/controllers/admins/project_languages_controller.rb b/app/controllers/admins/project_languages_controller.rb
index e188b75ef..0f26f25bb 100644
--- a/app/controllers/admins/project_languages_controller.rb
+++ b/app/controllers/admins/project_languages_controller.rb
@@ -3,8 +3,8 @@ class Admins::ProjectLanguagesController < Admins::BaseController
before_action :validate_names, only: [:create, :update]
def index
- sort_by = params[:sort_by] ||= 'created_at'
- sort_direction = params[:sort_direction] ||= 'desc'
+ sort_by = ProjectLanguage.column_names.include?(params[:sort_by]) ? params[:sort_by] : 'created_at'
+ sort_direction = %w(desc asc).include?(params[:sort_direction]) ? params[:sort_direction] : 'desc'
q = ProjectLanguage.ransack(name_cont: params[:search])
project_languages = q.result(distinct: true).order("#{sort_by} #{sort_direction}")
@project_languages = paginate(project_languages)
diff --git a/app/controllers/admins/project_licenses_controller.rb b/app/controllers/admins/project_licenses_controller.rb
index bc5789026..5c16a884b 100644
--- a/app/controllers/admins/project_licenses_controller.rb
+++ b/app/controllers/admins/project_licenses_controller.rb
@@ -3,8 +3,8 @@ class Admins::ProjectLicensesController < Admins::BaseController
before_action :validate_params, only: [:create, :update]
def index
- sort_by = params[:sort_by] ||= 'created_at'
- sort_direction = params[:sort_direction] ||= 'desc'
+ sort_by = License.column_names.include?(params[:sort_by]) ? params[:sort_by] : 'created_at'
+ sort_direction = %w(desc asc).include?(params[:sort_direction]) ? params[:sort_direction] : 'desc'
q = License.ransack(name_cont: params[:search])
project_licenses = q.result(distinct: true).order("#{sort_by} #{sort_direction}")
@project_licenses = paginate(project_licenses)
diff --git a/app/controllers/admins/projects_controller.rb b/app/controllers/admins/projects_controller.rb
index 2335db6d1..9e06eb1c9 100644
--- a/app/controllers/admins/projects_controller.rb
+++ b/app/controllers/admins/projects_controller.rb
@@ -1,9 +1,8 @@
class Admins::ProjectsController < Admins::BaseController
def index
- sort_by = params[:sort_by] ||= 'created_on'
- sort_direction = params[:sort_direction] ||= 'desc'
-
+ sort_by = Project.column_names.include?(params[:sort_by]) ? params[:sort_by] : 'created_on'
+ sort_direction = %w(desc asc).include?(params[:sort_direction]) ? params[:sort_direction] : 'desc'
search = params[:search].to_s.strip
projects = Project.where("name like ?", "%#{search}%").order("#{sort_by} #{sort_direction}")
@projects = paginate projects.includes(:owner, :members, :issues, :versions, :attachments, :project_score)
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 8536147ca..8b98a920b 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -615,8 +615,8 @@ class ApplicationController < ActionController::Base
end
# 排序
- rorder = option[:order] || "updated_at"
- b_order = option[:b_order] || "desc"
+ rorder = UserExtension.column_names.include?(option[:order]) ? option[:order] : "updated_at"
+ b_order = %w(desc asc).include?(option[:b_order]) ? option[:b_order] : "desc"
if rorder == "created_at" || rorder == "work_score"
work_list = work_list.order("graduation_works.#{rorder} #{b_order}")
elsif rorder == "student_id"
diff --git a/app/controllers/applied_projects_controller.rb b/app/controllers/applied_projects_controller.rb
new file mode 100644
index 000000000..e2f55b27a
--- /dev/null
+++ b/app/controllers/applied_projects_controller.rb
@@ -0,0 +1,13 @@
+class AppliedProjectsController < ApplicationController
+ before_action :require_login
+ def create
+ @applied_project = Projects::ApplyJoinService.call(current_user, applied_params)
+ rescue Projects::ApplyJoinService::Error => ex
+ render_error(ex.message)
+ end
+
+ private
+ def applied_params
+ params.require(:applied_project).permit(:code, :role)
+ end
+end
\ No newline at end of file
diff --git a/app/controllers/composes_controller.rb b/app/controllers/composes_controller.rb
index c1a7f524f..006604f29 100644
--- a/app/controllers/composes_controller.rb
+++ b/app/controllers/composes_controller.rb
@@ -3,13 +3,12 @@ class ComposesController < ApplicationController
before_action :find_compose, except: [:index, :new,:create]
def index
- @order_type = params[:order] || "created_at"
@search_name = params[:search]
composes = Compose.compose_includes
if @search_name.present?
composes = composes.where("title like ?", "%#{@search_name}%")
end
- composes = composes.order("#{@order_type} desc")
+ composes = composes.order("#{order_type} desc")
@page = params[:page] || 1
@limit = params[:limit] || 15
@composes_size = composes.size
@@ -96,4 +95,8 @@ class ComposesController < ApplicationController
end
end
+ def order_type
+ Compose.column_names.include?(params[:order_type]) ? params[:order_type] : 'created_at'
+ end
+
end
\ No newline at end of file
diff --git a/app/controllers/issue_tags_controller.rb b/app/controllers/issue_tags_controller.rb
index 312de7842..d21d8ed4f 100644
--- a/app/controllers/issue_tags_controller.rb
+++ b/app/controllers/issue_tags_controller.rb
@@ -7,9 +7,6 @@ class IssueTagsController < ApplicationController
def index
- order_name = params[:order_name] || "created_at"
- order_type = params[:order_type] || "desc"
-
issue_tags = @project.issue_tags.order("#{order_name} #{order_type}")
@user_admin_or_member = current_user.present? && (current_user.admin || @project.member?(current_user))
@page = params[:page] || 1
@@ -138,4 +135,14 @@ class IssueTagsController < ApplicationController
end
end
+ private
+
+ def order_name
+ IssueTag.column_names.include?(params[:order_name]) ? params[:order_name] : 'created_at'
+ end
+
+ def order_type
+ %w(desc asc).include?(params[:order_type]) ? params[:order_type] : 'desc'
+ end
+
end
diff --git a/app/controllers/issues_controller.rb b/app/controllers/issues_controller.rb
index 3584d6bf5..4b073415a 100644
--- a/app/controllers/issues_controller.rb
+++ b/app/controllers/issues_controller.rb
@@ -17,11 +17,15 @@ class IssuesController < ApplicationController
issues = @project.issues.issue_issue.issue_index_includes
issues = issues.where(is_private: false) unless @user_admin_or_member
- @all_issues_size = issues.size
- @open_issues_size = issues.where.not(status_id: 5).size
- @close_issues_size = issues.where(status_id: 5).size
- @assign_to_me_size = issues.where(assigned_to_id: current_user&.id).size
- @my_published_size = issues.where(author_id: current_user&.id).size
+ @all_issues = issues
+ @filter_issues = @all_issues
+ @filter_issues = @filter_issues.where.not(status_id: IssueStatus::CLOSED) if params[:status_type].to_i == IssueStatus::ADD
+ @filter_issues = @filter_issues.where(status_id: IssueStatus::CLOSED) if params[:status_type].to_i == IssueStatus::SOLVING
+ @filter_issues = @filter_issues.where("subject LIKE ? OR description LIKE ? ", "%#{params[:search]}%", "%#{params[:search]}%") if params[:search].present?
+ @open_issues = @all_issues.where.not(status_id: IssueStatus::CLOSED)
+ @close_issues = @all_issues.where(status_id: IssueStatus::CLOSED)
+ @assign_to_me = @filter_issues.where(assigned_to_id: current_user&.id)
+ @my_published = @filter_issues.where(author_id: current_user&.id)
scopes = Issues::ListQueryService.call(issues,params.delete_if{|k,v| v.blank?}, "Issue")
@issues_size = scopes.size
@issues = paginate(scopes)
diff --git a/app/controllers/members_controller.rb b/app/controllers/members_controller.rb
index fea57fa72..67aba25f4 100644
--- a/app/controllers/members_controller.rb
+++ b/app/controllers/members_controller.rb
@@ -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_WS(users.lastname, users.firstname, users.login, users.mail, users.nickname)) LIKE ?", "%#{search.split(" ").join('|')}%") if search.present?
+ scope = scope.joins(:user).merge(User.like(search))
scope = scope.joins(:roles).where("roles.name LIKE ?", "%#{role}%") if role.present?
@total_count = scope.size
diff --git a/app/controllers/organizations/organization_users_controller.rb b/app/controllers/organizations/organization_users_controller.rb
index d2d6963a4..1cddabc90 100644
--- a/app/controllers/organizations/organization_users_controller.rb
+++ b/app/controllers/organizations/organization_users_controller.rb
@@ -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, users.nickname)) LIKE ?", "%#{search.split(" ").join('|')}%") if search.present?
+ @organization_users = @organization_users.joins(:user).merge(User.like(search))
@organization_users = kaminari_paginate(@organization_users)
end
diff --git a/app/controllers/organizations/organizations_controller.rb b/app/controllers/organizations/organizations_controller.rb
index 7be9390d7..104db90ed 100644
--- a/app/controllers/organizations/organizations_controller.rb
+++ b/app/controllers/organizations/organizations_controller.rb
@@ -88,11 +88,11 @@ class Organizations::OrganizationsController < Organizations::BaseController
end
def sort_by
- params.fetch(:sort_by, "created_at")
+ OrganizationExtension.column_names.include?(params[:sort_by]) ? params[:sort_by] : 'created_at'
end
def sort_direction
- params.fetch(:sort_direction, "desc")
+ %w(desc asc).include?(params[:sort_direction]) ? params[:sort_direction] : 'desc'
end
end
\ No newline at end of file
diff --git a/app/controllers/organizations/projects_controller.rb b/app/controllers/organizations/projects_controller.rb
index cc275b090..b36a76125 100644
--- a/app/controllers/organizations/projects_controller.rb
+++ b/app/controllers/organizations/projects_controller.rb
@@ -36,10 +36,10 @@ class Organizations::ProjectsController < Organizations::BaseController
end
def sort
- params.fetch(:sort_by, "updated_on")
+ Project.column_names.include?(params[:sort_by]) ? params[:sort_by] : 'updated_on'
end
def sort_direction
- params.fetch(:sort_direction, "desc")
+ %w(desc asc).include?(params[:sort_direction]) ? params[:sort_direction] : 'desc'
end
end
\ No newline at end of file
diff --git a/app/controllers/organizations/team_users_controller.rb b/app/controllers/organizations/team_users_controller.rb
index d8694a6c5..752e1f0e5 100644
--- a/app/controllers/organizations/team_users_controller.rb
+++ b/app/controllers/organizations/team_users_controller.rb
@@ -8,7 +8,7 @@ class Organizations::TeamUsersController < Organizations::BaseController
@team_users = @team.team_users.includes(:user)
search = params[:search].to_s.downcase
- @team_users = @team_users.joins(:user).where("LOWER(CONCAT_WS(users.lastname, users.firstname, users.login, users.mail, users.nickname)) LIKE ?", "%#{search.split(" ").join('|')}%") if search.present?
+ @team_users = @team_users.joins(:user).merge(User.like(search))
@team_users = kaminari_paginate(@team_users)
end
diff --git a/app/controllers/pull_requests_controller.rb b/app/controllers/pull_requests_controller.rb
index 139ea9526..8521cd4b3 100644
--- a/app/controllers/pull_requests_controller.rb
+++ b/app/controllers/pull_requests_controller.rb
@@ -12,10 +12,12 @@ class PullRequestsController < ApplicationController
# @issues = Gitea::PullRequest::ListService.new(@user,@repository.try(:identifier)).call #通过gitea获取
issues = @project.issues.issue_pull_request.issue_index_includes.includes(pull_request: :user)
issues = issues.where(is_private: false) unless current_user.present? && (current_user.admin? || @project.member?(current_user))
- @all_issues_size = issues.size
- @open_issues_size = issues.joins(:pull_request).where(pull_requests: {status: 0}).size
- @close_issues_size = issues.joins(:pull_request).where(pull_requests: {status: 2}).size
- @merged_issues_size = issues.joins(:pull_request).where(pull_requests: {status: 1}).size
+ @all_issues = issues.distinct
+ @filter_issues = @all_issues
+ @filter_issues = @filter_issues.where("subject LIKE ? OR description LIKE ? ", "%#{params[:search]}%", "%#{params[:search]}%") if params[:search].present?
+ @open_issues = @filter_issues.joins(:pull_request).where(pull_requests: {status: PullRequest::OPEN})
+ @close_issues = @filter_issues.joins(:pull_request).where(pull_requests: {status: PullRequest::CLOSED})
+ @merged_issues = @filter_issues.joins(:pull_request).where(pull_requests: {status: PullRequest::MERGED})
@user_admin_or_member = current_user.present? && (current_user.admin || @project.member?(current_user))
scopes = Issues::ListQueryService.call(issues,params.delete_if{|k,v| v.blank?}, "PullRequest")
diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb
index 6594d06e9..93ba02a92 100644
--- a/app/controllers/repositories_controller.rb
+++ b/app/controllers/repositories_controller.rb
@@ -56,9 +56,7 @@ class RepositoriesController < ApplicationController
# TODO
# 临时处理readme文件问题
- admin = current_user.blank? ? User.where(admin: true).last : current_user
-
- result = Gitea::Repository::Readme::GetService.call(@owner.login, @project.identifier, @ref, admin&.gitea_token)
+ result = Gitea::Repository::Readme::GetService.call(@owner.login, @project.identifier, @ref, @owner&.gitea_token)
@readme =
if result[:status] == :success
result[:body]
diff --git a/app/controllers/users/applied_messages_controller.rb b/app/controllers/users/applied_messages_controller.rb
index e80cabf92..950caa2b3 100644
--- a/app/controllers/users/applied_messages_controller.rb
+++ b/app/controllers/users/applied_messages_controller.rb
@@ -9,7 +9,7 @@ class Users::AppliedMessagesController < Users::BaseController
private
def check_auth
- return render_forbidden unless observed_logged_user?
+ return render_forbidden unless current_user.admin? || observed_logged_user?
end
def view_messages
diff --git a/app/controllers/users/applied_projects_controller.rb b/app/controllers/users/applied_projects_controller.rb
new file mode 100644
index 000000000..3663a6d34
--- /dev/null
+++ b/app/controllers/users/applied_projects_controller.rb
@@ -0,0 +1,39 @@
+class Users::AppliedProjectsController < Users::BaseController
+ before_action :check_auth
+ before_action :find_applied_project, except: [:index]
+ before_action :find_project, except: [:index]
+
+ def index
+ @applied_projects = AppliedProject.where(project_id: observed_user.full_admin_projects)
+ @applied_projects = paginate @applied_projects.order("created_at desc")
+ end
+
+ # 接受申请
+ def accept
+ @applied_project = Projects::AcceptJoinService.call(current_user, @applied_project)
+ rescue Exception => e
+ uid_logger_error(e.message)
+ tip_exception(e.message)
+ end
+
+ # 拒绝申请
+ def refuse
+ @applied_project = Projects::RefuseJoinService.call(current_user, @applied_project)
+ rescue Exception => e
+ uid_logger_error(e.message)
+ tip_exception(e.message)
+ end
+
+ private
+ def check_auth
+ return render_forbidden unless current_user.admin? || observed_logged_user?
+ end
+
+ def find_applied_project
+ @applied_project = AppliedProject.find_by_id params[:id]
+ end
+
+ def find_project
+ @project = @applied_project.project
+ end
+end
\ No newline at end of file
diff --git a/app/controllers/users/applied_transfer_projects_controller.rb b/app/controllers/users/applied_transfer_projects_controller.rb
index b1777f526..a40833943 100644
--- a/app/controllers/users/applied_transfer_projects_controller.rb
+++ b/app/controllers/users/applied_transfer_projects_controller.rb
@@ -28,7 +28,7 @@ class Users::AppliedTransferProjectsController < Users::BaseController
private
def check_auth
- return render_forbidden unless observed_logged_user?
+ return render_forbidden unless current_user.admin? || observed_logged_user?
end
def find_applied_transfer_project
diff --git a/app/controllers/users/banks_controller.rb b/app/controllers/users/banks_controller.rb
index 2c792151e..99a55e6c4 100644
--- a/app/controllers/users/banks_controller.rb
+++ b/app/controllers/users/banks_controller.rb
@@ -1,8 +1,8 @@
class Users::BanksController < Users::BaseController
before_action :params_filter
def index
- order = params[:order] || "updated_at"
- sort = params[:sort] || "desc"
+ order = CourseList.column_names.include?(params[:order]) ? params[:order] : "updated_at"
+ sort = %w(desc asc).includes?(params[:sort]) ? params[:sort] : "desc"
@banks = @object_type.classify.constantize.where(@object_filter)
@course_lists = CourseList.where(id: @banks.pluck(:course_list_id))
@banks = @banks.where(course_list_id: params[:tag_id]) unless params[:tag_id].blank?
diff --git a/app/controllers/users/organizations_controller.rb b/app/controllers/users/organizations_controller.rb
index 721339e84..2d949da7d 100644
--- a/app/controllers/users/organizations_controller.rb
+++ b/app/controllers/users/organizations_controller.rb
@@ -16,10 +16,10 @@ class Users::OrganizationsController < Users::BaseController
private
def sort_by
- params.fetch(:sort_by, "created_at")
+ OrganizationExtension.column_names.include?(params[:sort_by]) ? params[:sort_by] : 'created_at'
end
def sort_direction
- params.fetch(:sort_direction, "desc")
+ %w(desc asc).include?(params[:sort_direction]) ? params[:sort_direction] : 'desc'
end
end
\ No newline at end of file
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index 163b5849f..a0184a348 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -28,13 +28,15 @@ class UsersController < ApplicationController
def show
#待办事项,现在未做
- if User.current.login == @user.login
+ if User.current.admin? || User.current.login == @user.login
@waiting_applied_messages = @user.applied_messages.waiting
@common_applied_transfer_projects = AppliedTransferProject.where(owner_id: @user.id).common + AppliedTransferProject.where(owner_id: Organization.joins(team_users: :team).where(team_users: {user_id: @user.id}, teams: {authorize: %w(admin owner)} )).common
- @undo_events = @waiting_applied_messages.size + @common_applied_transfer_projects.size
+ @common_applied_projects = AppliedProject.where(project_id: @user.full_admin_projects).common
+ @undo_events = @waiting_applied_messages.size + @common_applied_transfer_projects.size + @common_applied_projects.size
else
@waiting_applied_messages = AppliedMessage.none
@common_applied_transfer_projects = AppliedTransferProject.none
+ @common_applied_projects = AppliedProject.none
@undo_events = 0
end
#用户的组织数量
@@ -63,8 +65,7 @@ class UsersController < ApplicationController
def fan_users
watchers = @user.watchers.includes(:user).order("watchers.created_at desc")
- 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 = watchers.joins(:user).merge(User.like(params[:search]))
@watchers_count = watchers.size
@watchers = paginate(watchers)
end
diff --git a/app/controllers/users_for_private_messages_controller.rb b/app/controllers/users_for_private_messages_controller.rb
index 3a53a1af8..8f73bb36b 100644
--- a/app/controllers/users_for_private_messages_controller.rb
+++ b/app/controllers/users_for_private_messages_controller.rb
@@ -11,7 +11,7 @@ class UsersForPrivateMessagesController < ApplicationController
return
end
- users = users.where('LOWER(CONCAT_WS(lastname, firstname, nickname)) LIKE ?', "%#{keyword}%")
+ users = users.like(keyword)
@users = users.limit(10).includes(:user_extension)
end
diff --git a/app/controllers/versions_controller.rb b/app/controllers/versions_controller.rb
index 02700fdf5..f5d09ed3b 100644
--- a/app/controllers/versions_controller.rb
+++ b/app/controllers/versions_controller.rb
@@ -7,8 +7,6 @@ class VersionsController < ApplicationController
def index
return render_not_found unless @project.has_menu_permission("versions")
@user_admin_or_member = current_user.present? && (current_user.admin || @project.member?(current_user))
- order_name = params[:order_name] || "created_on"
- order_type = params[:order_type] || "desc"
status = params[:status]
versions = @project.versions.version_includes
@open_versions_size = versions.where(status: "open")&.size
@@ -27,9 +25,6 @@ class VersionsController < ApplicationController
end
def show
- order_name = params[:order_name] || "created_on"
- order_type = params[:order_type] || "desc"
-
version_issues = @version.issues.issue_includes
status_type = params[:status_type] || "1"
@@ -167,4 +162,12 @@ class VersionsController < ApplicationController
end
end
+ def order_name
+ Version.column_names.include?(params[:order_name]) ? params[:order_name] : 'created_on'
+ end
+
+ def order_type
+ %w(desc asc).include?(params[:order_type]) ? params[:order_type] : 'desc'
+ end
+
end
diff --git a/app/controllers/weapps/courses_controller.rb b/app/controllers/weapps/courses_controller.rb
index 72782f5cc..d7ac903ed 100644
--- a/app/controllers/weapps/courses_controller.rb
+++ b/app/controllers/weapps/courses_controller.rb
@@ -86,7 +86,7 @@ class Weapps::CoursesController < Weapps::BaseController
end
if search.present?
- @teacher_list = @teacher_list.joins(:user).where("LOWER(CONCAT_WS(users.lastname, users.firstname, users.nickname)) like ?", "%#{search}%")
+ @teacher_list = @teacher_list.joins(:user).where("LOWER(CONCAT(users.lastname, users.firstname)) like ? OR users.nickname like ?", "%#{search}%", "%#{search}%")
end
@teacher_list_size = @teacher_list.size
@@ -127,8 +127,8 @@ class Weapps::CoursesController < Weapps::BaseController
@students = CourseMember.students(@course)
if search.present?
- @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}%")
+ @students = @students.joins(user: :user_extension).where("LOWER(CONCAT(users.lastname, users.firstname)) like ? or users.nickname like ? or
+ user_extensions.student_id like ?", "%#{search}%", "%#{search}%", "%#{search}%")
end
if course_group_id.present?
diff --git a/app/controllers/zips_controller.rb b/app/controllers/zips_controller.rb
index 0c226211f..287891403 100644
--- a/app/controllers/zips_controller.rb
+++ b/app/controllers/zips_controller.rb
@@ -86,7 +86,7 @@ class ZipsController < ApplicationController
#搜索
if params[:search].present?
- @ex_users = @ex_users.joins(user: :user_extension).where("CONCAT_WS(lastname, firstname, nickname) like ? OR student_id like ?", "%#{params[:search]}%", "%#{params[:search]}%")
+ @ex_users = @ex_users.joins(user: :user_extension).where("CONCAT(lastname, firstname) like ? OR nickname like ? OR student_id like ?", "%#{params[:search]}%", "%#{params[:search]}%", "%#{params[:search]}%")
end
default_ex_users_size = @ex_users&.size
@@ -130,8 +130,8 @@ class ZipsController < ApplicationController
end
unless params[:search].blank?
- @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]}%")
+ @all_student_works = @all_student_works.joins(user: :user_extension).where("CONCAT(lastname, firstname) like ? or nickname like ?
+ or student_id like ?", "%#{params[:search]}%", "%#{params[:search]}%", "%#{params[:search]}%")
end
student_work_sizes = @all_student_works&.size
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index ccc45df0e..a1aea4aeb 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -438,4 +438,14 @@ module ApplicationHelper
return nil if str.blank?
Base64.decode64 str
end
+
+ def render_admin_statistics_item
+ url = Rails.application.config_for(:configuration)["admin_statistics_url"]
+
+ return if url.blank?
+ content_tag(:li) do
+ sidebar_item(url, "数据统计", icon: 'bar-chart', controller: 'root')
+ end
+ end
+
end
diff --git a/app/interactors/gitea/create_file_interactor.rb b/app/interactors/gitea/create_file_interactor.rb
index acceeaa97..389813520 100644
--- a/app/interactors/gitea/create_file_interactor.rb
+++ b/app/interactors/gitea/create_file_interactor.rb
@@ -24,8 +24,14 @@ module Gitea
def run
Contents::CreateForm.new(valid_params).validate!
- response = Gitea::Repository::Entries::CreateService.new(token, owner, @params[:identifier], @params[:filepath], file_params).call
- render_result(response)
+ result = Gitea::Repository::Entries::CreateService.call(token,
+ owner, @params[:identifier], @params[:filepath], file_params)
+
+ if result[:status] == :success
+ @result = result[:body]
+ else
+ fail!(result[:message])
+ end
rescue Exception => exception
Rails.logger.info "Exception ===========> #{exception.message}"
fail!(exception.message)
@@ -56,7 +62,7 @@ module Gitea
file_params = {}
file_params = file_params.merge(branch: @params[:branch]) unless @params[:branch].blank?
file_params = file_params.merge(new_branch: @params[:new_branch]) unless @params[:new_branch].blank?
- file_params = file_params.merge(content: Base64.encode64(@params[:content]))
+ file_params = file_params.merge(content: Base64.encode64(@params[:content] || ""))
file_params = file_params.merge(message: @params[:message]) unless @params[:message].blank?
file_params = file_params.merge(committer: @params[:committer])
file_params
diff --git a/app/interactors/projects/add_member_interactor.rb b/app/interactors/projects/add_member_interactor.rb
index a3fe9e33e..0c3785c69 100644
--- a/app/interactors/projects/add_member_interactor.rb
+++ b/app/interactors/projects/add_member_interactor.rb
@@ -23,7 +23,7 @@ module Projects
ActiveRecord::Base.transaction do
gitea_result = Gitea::Repository::Members::AddService.new(owner, project.identifier, collaborator.login, permission).call
if gitea_result.status == 204
- project.add_member!(collaborator.id)
+ project.add_member!(collaborator.id, role_name)
end
fail!(nil)
end
@@ -38,5 +38,20 @@ module Projects
@error = error
end
+ def role_name
+ case permission
+ when 'read'
+ 'Reporter'
+ when 'write'
+ 'Developer'
+ when 'admin'
+ 'Manager'
+ when 'owner'
+ 'Manager'
+ else
+ 'Reporter'
+ end
+ end
+
end
end
diff --git a/app/jobs/send_join_project_applied_message_job.rb b/app/jobs/send_join_project_applied_message_job.rb
new file mode 100644
index 000000000..557878ede
--- /dev/null
+++ b/app/jobs/send_join_project_applied_message_job.rb
@@ -0,0 +1,27 @@
+class SendJoinProjectAppliedMessageJob < ApplicationJob
+ queue_as :default
+
+ def perform(applied_project, applied_user, message_status)
+ project = applied_project.project
+ return unless project.present?
+ return unless applied_user.present?
+ return unless applied_project.user.present?
+ AppliedMessage.find_or_create_by!(user_id: applied_project.user_id,
+ applied: applied_project,
+ status: message_status,
+ name: build_name(project.name, message_status),
+ applied_user_id: applied_user.id,
+ project_id: project.id)
+ end
+
+ private
+ def build_name(repo_name, message_status, applied_name="")
+ case message_status
+ when 'successed'
+ return "已通过你加入【#{repo_name}】仓库的申请。"
+ when 'failure'
+ return "已拒绝你加入【#{repo_name}】仓库的申请。"
+ end
+ ""
+ end
+end
\ No newline at end of file
diff --git a/app/models/applied_message.rb b/app/models/applied_message.rb
index b3ebad34e..5c942b7b3 100644
--- a/app/models/applied_message.rb
+++ b/app/models/applied_message.rb
@@ -17,6 +17,7 @@
#
class AppliedMessage < ApplicationRecord
+ self.table_name = 'forge_applied_messages'
belongs_to :user
belongs_to :applied, polymorphic: true
belongs_to :project
diff --git a/app/models/applied_project.rb b/app/models/applied_project.rb
index 68095d0ea..e0b4b6c48 100644
--- a/app/models/applied_project.rb
+++ b/app/models/applied_project.rb
@@ -7,14 +7,19 @@
# user_id :integer not null
# role :integer default("0")
# status :integer default("0")
+# created_at :datetime
+# updated_at :datetime
#
class AppliedProject < ApplicationRecord
+ self.table_name = "forge_applied_projects"
belongs_to :user
belongs_to :project
has_many :applied_messages, as: :applied, dependent: :destroy
- has_many :forge_activities, as: :forge_act, dependent: :destroy
+ # has_many :forge_activities, as: :forge_act, dependent: :destroy
+
+ enum role: {manager: 3, developer: 4, reporter: 5}
+ enum status: {canceled: -1, common: 0, accepted: 1, refused: 2} # -1 已取消 0 待操作 1 已接收 2 已拒绝
- scope :pending, -> { where(status: 0) }
end
diff --git a/app/models/attachment.rb b/app/models/attachment.rb
index 3bfc9a8ce..c6a50d93e 100644
--- a/app/models/attachment.rb
+++ b/app/models/attachment.rb
@@ -37,6 +37,7 @@
# index_attachments_on_quotes (quotes)
#
+
class Attachment < ApplicationRecord
include BaseModel
include Publicable
@@ -51,7 +52,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_WS(users.lastname, users.firstname, users.nickname)) LIKE :search",
+ scope :by_filename_or_user_name, -> (keywords) { joins(:author).where("filename like :search or LOWER(CONCAT(users.lastname, users.firstname)) LIKE :search OR 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'}") }
diff --git a/app/models/ci/user.rb b/app/models/ci/user.rb
index cd6246753..c263a1723 100644
--- a/app/models/ci/user.rb
+++ b/app/models/ci/user.rb
@@ -46,6 +46,10 @@
# is_sync_pwd :boolean default("1")
# watchers_count :integer default("0")
# devops_step :integer default("0")
+# sponsor_certification :integer default("0")
+# sponsor_num :integer default("0")
+# sponsored_num :integer default("0")
+# award_time :datetime
#
# Indexes
#
diff --git a/app/models/concerns/dcodes.rb b/app/models/concerns/dcodes.rb
new file mode 100644
index 000000000..6c2ff13b0
--- /dev/null
+++ b/app/models/concerns/dcodes.rb
@@ -0,0 +1,28 @@
+module Dcodes
+ DCODES = %W(1 2 3 4 5 6 7 8 9 a b c f e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z)
+
+ extend ActiveSupport::Concern
+
+ def generate_dcode(field, num, pre='')
+ code = DCODES.sample(num).join
+ while self.class.exists?("#{field}": pre+code) do
+ code = DCODES.sample(num).join
+ end
+ code
+ end
+
+ def init_project_invite_code
+ while Project.where(invite_code: nil).size > 0 do
+ projects = Project.where(invite_code: nil).limit(1000)
+ set_sql = ""
+ projects.each do |p|
+ set_sql += "WHEN #{p.id} THEN '#{DCODES.sample(6).join}' "
+ end
+ sql = "UPDATE projects SET invite_code = CASE id "+ set_sql+ "END WHERE id IN(#{projects.ids.join(",")})"
+ Project.connection.execute(sql)
+ end
+ repeat_codes = Project.group(:invite_code).count.select{|k,v| v>1}
+ Project.where(invite_code: repeat_code.keys).update_all(invite_code: nil)
+ end
+
+end
\ No newline at end of file
diff --git a/app/models/concerns/project_operable.rb b/app/models/concerns/project_operable.rb
index e016ca1dc..79d099a2e 100644
--- a/app/models/concerns/project_operable.rb
+++ b/app/models/concerns/project_operable.rb
@@ -65,7 +65,7 @@ module ProjectOperable
if owner.is_a?(User)
managers.exists?(user_id: user.id)
elsif owner.is_a?(Organization)
- managers.exists?(user_id: user.id) || owner.is_admin?(user.id)
+ managers.exists?(user_id: user.id) || owner.is_only_admin?(user.id)
else
false
end
@@ -76,7 +76,7 @@ module ProjectOperable
if owner.is_a?(User)
developers.exists?(user_id: user.id)
elsif owner.is_a?(Organization)
- developers.exists?(user_id: user.id) || owner.is_write?(user.id)
+ developers.exists?(user_id: user.id) || owner.is_only_write?(user.id)
else
false
end
diff --git a/app/models/issue.rb b/app/models/issue.rb
index b43f5a3d2..826ad3a5b 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -6,7 +6,7 @@
# tracker_id :integer not null
# project_id :integer not null
# subject :string(255) default(""), not null
-# description :text(65535)
+# description :text(4294967295)
# due_date :date
# category_id :integer
# status_id :integer not null
@@ -14,7 +14,6 @@
# 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
@@ -28,7 +27,7 @@
# closed_on :datetime
# project_issues_index :integer
# issue_type :string(255)
-# token :string(255)
+# token :integer default("0")
# issue_tags_value :string(255)
# is_lock :boolean default("0")
# issue_classify :string(255)
@@ -74,7 +73,7 @@ class Issue < ApplicationRecord
scope :issue_issue, ->{where(issue_classify: [nil,"issue"])}
scope :issue_pull_request, ->{where(issue_classify: "pull_request")}
scope :issue_index_includes, ->{includes(:tracker, :priority, :version, :issue_status, :journals,:issue_tags,user: :user_extension)}
-
+ scope :closed, ->{where(status_id: 5)}
after_update :change_versions_count
after_save :reset_cache_data
after_destroy :update_closed_issues_count_in_project!, :reset_cache_data
diff --git a/app/models/license.rb b/app/models/license.rb
index 0a14fb85e..dcd5528fb 100644
--- a/app/models/license.rb
+++ b/app/models/license.rb
@@ -7,6 +7,7 @@
# content :text(65535)
# created_at :datetime not null
# updated_at :datetime not null
+# is_secret :boolean default("0")
#
class License < ApplicationRecord
diff --git a/app/models/member.rb b/app/models/member.rb
index e72ae7c6b..408710a03 100644
--- a/app/models/member.rb
+++ b/app/models/member.rb
@@ -11,6 +11,7 @@
# course_group_id :integer default("0")
# is_collect :integer default("1")
# graduation_group_id :integer default("0")
+# is_apply_signature :boolean default("0")
#
# Indexes
#
diff --git a/app/models/organization.rb b/app/models/organization.rb
index 988ecd7fb..666e13ff2 100644
--- a/app/models/organization.rb
+++ b/app/models/organization.rb
@@ -46,6 +46,10 @@
# is_sync_pwd :boolean default("1")
# watchers_count :integer default("0")
# devops_step :integer default("0")
+# sponsor_certification :integer default("0")
+# sponsor_num :integer default("0")
+# sponsored_num :integer default("0")
+# award_time :datetime
#
# Indexes
#
@@ -106,6 +110,14 @@ class Organization < Owner
team_users.joins(:team).where(user_id: user_id, teams: {authorize: %w(read write admin owner)}).present?
end
+ def is_only_admin?(user_id)
+ team_users.joins(:team).where(user_id: user_id, teams: {authorize: %w(admin)}).present?
+ end
+
+ def is_only_write?(user_id)
+ team_users.joins(:team).where(user_id: user_id, teams: {authorize: %w(write)}).present?
+ end
+
def is_only_read?(user_id)
team_users.joins(:team).where(user_id: user_id, teams: {authorize: %w(read)}).present?
end
diff --git a/app/models/praise_tread.rb b/app/models/praise_tread.rb
index 04008eaf6..5a9c19164 100644
--- a/app/models/praise_tread.rb
+++ b/app/models/praise_tread.rb
@@ -1,19 +1,20 @@
-# == 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
diff --git a/app/models/project.rb b/app/models/project.rb
index b61f05689..eb8a0bbf4 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -1,63 +1,78 @@
-# == 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)
-#
+# == 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
+# 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")
+# 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")
+# default_branch :string(255) default("master")
+# website :string(255)
+# order_index :integer default("0")
+# lesson_url :string(255)
+#
+# Indexes
+#
+# index_projects_on_forked_from_project_id (forked_from_project_id)
+# index_projects_on_identifier (identifier)
+# index_projects_on_invite_code (invite_code)
+# 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)
+#
+
@@ -66,6 +81,7 @@ class Project < ApplicationRecord
include Publicable
include Watchable
include ProjectOperable
+ include Dcodes
# common:开源托管项目
# mirror:普通镜像项目,没有定时同步功能
@@ -106,6 +122,7 @@ class Project < ApplicationRecord
has_many :has_pinned_users, through: :pinned_projects, source: :user
after_save :check_project_members, :reset_cache_data
+ before_save :set_invite_code
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)}
@@ -123,6 +140,12 @@ class Project < ApplicationRecord
self.reset_user_cache_async_job(self.owner)
end
+ def set_invite_code
+ if self.invite_code.nil?
+ self.invite_code= self.generate_dcode('invite_code', 6)
+ end
+ end
+
def self.search_project(search)
ransack(name_or_identifier_cont: search)
end
diff --git a/app/models/pull_request.rb b/app/models/pull_request.rb
index 97f4a9164..4226d561b 100644
--- a/app/models/pull_request.rb
+++ b/app/models/pull_request.rb
@@ -16,6 +16,11 @@
# 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
@@ -33,6 +38,9 @@ class PullRequest < ApplicationRecord
has_many :project_trends, as: :trend, dependent: :destroy
has_many :attachments, as: :container, dependent: :destroy
+ scope :merged_and_closed, ->{where.not(status: 0)}
+ scope :opening, -> {where(status: 0)}
+
after_save :reset_cache_data
after_destroy :reset_cache_data
diff --git a/app/models/user.rb b/app/models/user.rb
index 9d917f4c8..c943e5efa 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -46,6 +46,10 @@
# is_sync_pwd :boolean default("1")
# watchers_count :integer default("0")
# devops_step :integer default("0")
+# sponsor_certification :integer default("0")
+# sponsor_num :integer default("0")
+# sponsored_num :integer default("0")
+# award_time :datetime
#
# Indexes
#
@@ -170,7 +174,7 @@ class User < Owner
# Groups and active users
scope :active, lambda { where(status: STATUS_ACTIVE) }
scope :like, lambda { |keywords|
- sql = "CONCAT_WS(lastname, firstname, nickname) LIKE :search OR login LIKE :search OR mail LIKE :search OR nickname LIKE :search"
+ sql = "CONCAT(lastname, firstname) LIKE :search OR nickname LIKE :search OR login LIKE :search OR mail LIKE :search OR nickname LIKE :search"
where(sql, :search => "%#{keywords.split(" ").join('|')}%") unless keywords.blank?
}
@@ -206,6 +210,13 @@ class User < Owner
return Project.from("( #{ normal_projects} UNION #{ org_projects } ) AS projects").distinct
end
+ # 用户管理的所有项目
+ def full_admin_projects
+ normal_projects = Project.joins(members: :roles).where(roles: {name: 'Manager'}, members: {user_id: self.id}).to_sql
+ org_projects = Project.joins(teams: :team_users).where(teams: {authorize: %w(admin owner)}, team_users: {user_id: self.id}).to_sql
+ return Project.from("( #{ normal_projects} UNION #{ org_projects } ) AS projects").distinct
+ end
+
def name
login
end
diff --git a/app/models/version.rb b/app/models/version.rb
index 650d5a656..77cb58a7e 100644
--- a/app/models/version.rb
+++ b/app/models/version.rb
@@ -29,6 +29,8 @@ class Version < ApplicationRecord
belongs_to :user, optional: true
scope :version_includes, ->{includes(:issues, :user)}
+ scope :closed, ->{where(status: 'closed')}
+ scope :opening, ->{where(status: 'open')}
# def open_issues_count
# issues.select(:id,:status_id).where(status_id: [1,2,3,4,6]).size
diff --git a/app/queries/admins/apply_item_bank_query.rb b/app/queries/admins/apply_item_bank_query.rb
index 922d136ef..8608e238d 100644
--- a/app/queries/admins/apply_item_bank_query.rb
+++ b/app/queries/admins/apply_item_bank_query.rb
@@ -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_WS(lastname,firstname, nickname) LIKE :keyword OR schools.name LIKE :keyword', keyword: "%#{keyword}%")
+ .where('CONCAT(lastname,firstname) LIKE :keyword OR users.nickname LIKE :keyword OR schools.name LIKE :keyword', keyword: "%#{keyword}%")
end
custom_sort(applies, params[:sort_by], params[:sort_direction])
diff --git a/app/queries/admins/apply_user_authentication_query.rb b/app/queries/admins/apply_user_authentication_query.rb
index 60b781d1c..741f28e5a 100644
--- a/app/queries/admins/apply_user_authentication_query.rb
+++ b/app/queries/admins/apply_user_authentication_query.rb
@@ -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_WS(lastname,firstname,nickname) LIKE :keyword OR schools.name LIKE :keyword', keyword: "%#{keyword}%")
+ .where('CONCAT(lastname,firstname) LIKE :keyword OR users.nickname LIKE :keyword OR schools.name LIKE :keyword', keyword: "%#{keyword}%")
end
custom_sort(applies, params[:sort_by], params[:sort_direction])
diff --git a/app/queries/admins/course_list_query.rb b/app/queries/admins/course_list_query.rb
index b97a9cebe..84868b7d0 100644
--- a/app/queries/admins/course_list_query.rb
+++ b/app/queries/admins/course_list_query.rb
@@ -19,7 +19,7 @@ class Admins::CourseListQuery < ApplicationQuery
case search_type
when "0"
course_lists = course_lists.joins(:user)
- .where('CONCAT_WS(lastname, firstname, nickname) like :keyword', keyword: "%#{keyword}%")
+ .where('CONCAT(lastname, firstname) like :keyword OR users.nickname like :keyword', keyword: "%#{keyword}%")
when "1"
course_lists = course_lists.where('name like :keyword', keyword: "%#{keyword}%")
end
diff --git a/app/queries/admins/course_query.rb b/app/queries/admins/course_query.rb
index b1466e22f..6fbbc002e 100644
--- a/app/queries/admins/course_query.rb
+++ b/app/queries/admins/course_query.rb
@@ -35,7 +35,7 @@ class Admins::CourseQuery < ApplicationQuery
# 关键字
keyword = params[:keyword].to_s.strip
if keyword
- sql = 'CONCAT_WS(lastname, firstname, nickname) LIKE :keyword OR courses.name LIKE :keyword OR course_lists.name LIKE :keyword'
+ sql = 'CONCAT(lastname, firstname) LIKE :keyword OR users.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
diff --git a/app/queries/admins/laboratory_shixun_query.rb b/app/queries/admins/laboratory_shixun_query.rb
index 9b9bf6a21..da7867194 100644
--- a/app/queries/admins/laboratory_shixun_query.rb
+++ b/app/queries/admins/laboratory_shixun_query.rb
@@ -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_WS(users.lastname, users.firstname, users.nickname) LIKE :keyword'
+ like_sql = 'shixuns.name LIKE :keyword OR CONCAT(users.lastname, users.firstname) LIKE :keyword OR users.nickname LIKE :keyword'
laboratory_shixuns = laboratory_shixuns.joins(shixun: :user).where(like_sql, keyword: "%#{keyword}%")
end
diff --git a/app/queries/admins/laboratory_subject_query.rb b/app/queries/admins/laboratory_subject_query.rb
index 619aeb2c2..d47463332 100644
--- a/app/queries/admins/laboratory_subject_query.rb
+++ b/app/queries/admins/laboratory_subject_query.rb
@@ -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_WS(users.lastname, users.firstname, users.nickname) LIKE :keyword'
+ like_sql = 'subjects.name LIKE :keyword OR CONCAT(users.lastname, users.firstname) LIKE :keyword OR users.nickname LIKE :keyword'
laboratory_subjects = laboratory_subjects.joins(subject: :user).where(like_sql, keyword: "%#{keyword}%")
end
diff --git a/app/queries/admins/subject_query.rb b/app/queries/admins/subject_query.rb
index df2ac40ef..3596c7715 100644
--- a/app/queries/admins/subject_query.rb
+++ b/app/queries/admins/subject_query.rb
@@ -40,7 +40,7 @@ class Admins::SubjectQuery < ApplicationQuery
# 关键字
keyword = params[:keyword].to_s.strip
if keyword
- sql = 'CONCAT_WS(lastname, firstname, nickname) LIKE :keyword OR subjects.name LIKE :keyword'
+ sql = 'CONCAT(lastname, firstname) LIKE :keyword OR users.nickname LIKE :keyword OR subjects.name LIKE :keyword'
subjects = subjects.joins(:user).where(sql, keyword: "%#{keyword}%")
end
diff --git a/app/queries/admins/user_query.rb b/app/queries/admins/user_query.rb
index 670eef58d..f9506ddf5 100644
--- a/app/queries/admins/user_query.rb
+++ b/app/queries/admins/user_query.rb
@@ -30,14 +30,14 @@ class Admins::UserQuery < ApplicationQuery
# 关键字检索
keyword = params[:keyword].to_s.strip.presence
if keyword
- sql = 'CONCAT_WS(lastname, firstname, nickname) LIKE :keyword OR login LIKE :keyword OR mail LIKE :keyword OR phone LIKE :keyword'
+ sql = 'CONCAT(lastname, firstname) LIKE :keyword OR 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_WS(lastname, firstname, nickname) LIKE :name', name: "%#{name}%")
+ users = users.where('CONCAT(lastname, firstname) LIKE :name OR nickname LIKE :name', name: "%#{name}%")
end
# 单位ID
diff --git a/app/queries/projects/list_my_query.rb b/app/queries/projects/list_my_query.rb
index c9f4544df..f275d63a5 100644
--- a/app/queries/projects/list_my_query.rb
+++ b/app/queries/projects/list_my_query.rb
@@ -55,8 +55,8 @@ class Projects::ListMyQuery < ApplicationQuery
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"
+ sort = Project.column_names.include?(params[:sort_by]) ? params[:sort_by] : "updated_on"
+ sort_direction = %w(desc asc).include?(params[:sort_direction]) ? params[:sort_direction] : "desc"
if params[:choosed].present? && params[:choosed].is_a?(Array)
scope.order("FIELD(id, #{params[:choosed].reverse.join(",")}) desc")
diff --git a/app/queries/user_query.rb b/app/queries/user_query.rb
index f2964c7dc..6668da5c7 100644
--- a/app/queries/user_query.rb
+++ b/app/queries/user_query.rb
@@ -10,7 +10,7 @@ class UserQuery < ApplicationQuery
# 真实姓名
if name = strip_param(:name)
- users = users.where('LOWER(CONCAT_WS(users.lastname, users.firstname, users.nickname)) LIKE ?', "%#{name.downcase}%")
+ users = users.where('LOWER(CONCAT(users.lastname, users.firstname)) LIKE ? OR users.nickname LIKE ?', "%#{name.downcase}%", "%#{name.downcase}%")
end
# 单位名称
diff --git a/app/queries/weapps/subject_query.rb b/app/queries/weapps/subject_query.rb
index e2f5625e1..73e70160a 100644
--- a/app/queries/weapps/subject_query.rb
+++ b/app/queries/weapps/subject_query.rb
@@ -28,10 +28,10 @@ class Weapps::SubjectQuery < ApplicationQuery
private
def order_type
- params[:order] || "updated_at"
+ Subject.column_names.include?(params[:order]) ? params[:order] : 'updated_at'
end
def sort_type
- params[:sort] || "desc"
+ %w(desc asc).include?(params[:sort]) ? params[:sort] : "desc"
end
end
\ No newline at end of file
diff --git a/app/services/admins/import_user_service.rb b/app/services/admins/import_user_service.rb
index 298bf1e16..5d4c2e10f 100644
--- a/app/services/admins/import_user_service.rb
+++ b/app/services/admins/import_user_service.rb
@@ -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_WS(users.lastname,users.firstname,users.nickname) = ?', data.name)
+ users = users.where(user_extensions: { technical_title: data.technical_title }).where('CONCAT(users.lastname,users.firstname) = ? OR users.nickname = ?', data.name, data.name)
end
users.first
diff --git a/app/services/gitea/client_service.rb b/app/services/gitea/client_service.rb
index 0ef041997..b88d8382a 100644
--- a/app/services/gitea/client_service.rb
+++ b/app/services/gitea/client_service.rb
@@ -214,6 +214,14 @@ class Gitea::ClientService < ApplicationService
[body, message]
end
+ def json_parse!(body)
+ return nil unless body.present?
+
+ body = JSON.parse(body)
+ body, message = fix_body(body)
+ body
+ end
+
def log_error(status, body)
puts "[gitea] status: #{status}"
puts "[gitea] body: #{body&.force_encoding('UTF-8')}"
diff --git a/app/services/gitea/repository/entries/create_service.rb b/app/services/gitea/repository/entries/create_service.rb
index 9f5abad2a..5e1a4c4b3 100644
--- a/app/services/gitea/repository/entries/create_service.rb
+++ b/app/services/gitea/repository/entries/create_service.rb
@@ -30,8 +30,7 @@ class Gitea::Repository::Entries::CreateService < Gitea::ClientService
def call
response = post(url, params)
-
- render_201_response(response)
+ response_payload(response)
end
private
@@ -43,4 +42,21 @@ class Gitea::Repository::Entries::CreateService < Gitea::ClientService
"/repos/#{owner}/#{repo_name}/contents/#{filepath}".freeze
end
+ def response_payload(response)
+ status = response.status
+ body = response&.body
+
+ log_error(status, body)
+ status_payload(status, body)
+ end
+
+ def status_payload(status, body)
+ case status
+ when 201 then success(json_parse!(body))
+ when 403 then error("你没有权限操作!")
+ when 404 then error("你操作的链接不存在!")
+ when 422 then error("#{filepath}文件已存在,不能重复创建!")
+ else error("系统错误!")
+ end
+ end
end
diff --git a/app/services/issues/list_query_service.rb b/app/services/issues/list_query_service.rb
index 1718db97d..f85e2cb9d 100644
--- a/app/services/issues/list_query_service.rb
+++ b/app/services/issues/list_query_service.rb
@@ -45,9 +45,17 @@ class Issues::ListQueryService < ApplicationService
issues = issues.where(issue_type: params[:issue_type].to_s) if params[:issue_type].present? && params[:issue_type].to_s != "all"
issues = issues.joins(:issue_tags).where(issue_tags: {id: params[:issue_tag_id].to_i}) if params[:issue_tag_id].present? && params[:issue_tag_id].to_s != "all"
- order_type = params[:order_type] || "desc" #或者"asc"
- order_name = params[:order_name] || "updated_on" #或者"updated_on"
issues.reorder("issues.#{order_name} #{order_type}")
end
+ private
+
+ def order_name
+ Issue.column_names.include?(params[:order_name]) ? params[:order_name] : 'updated_on'
+ end
+
+ def order_type
+ %w(desc asc).include?(params[:order_type]) ? params[:order_type] : 'desc'
+ end
+
end
\ No newline at end of file
diff --git a/app/services/projects/accept_join_service.rb b/app/services/projects/accept_join_service.rb
new file mode 100644
index 000000000..69cb97603
--- /dev/null
+++ b/app/services/projects/accept_join_service.rb
@@ -0,0 +1,61 @@
+class Projects::AcceptJoinService < ApplicationService
+ attr_accessor :applied_project, :owner
+ attr_reader :user, :project
+
+ def initialize(user, applied_project)
+ @user = user
+ @project = applied_project.project
+ @applied_project = applied_project
+ end
+
+ def call
+ Rails.logger.info("###### Project accept_join_service begin ######")
+ ActiveRecord::Base.transaction do
+ validate!
+ update_apply
+ operate_project_member
+ send_apply_message
+ end
+
+ Rails.logger.info("##### Project accept_join_service end ######")
+
+
+ return @applied_project
+ end
+
+ private
+ def permission
+ case @applied_project.role
+ when 'manager'
+ 'admin'
+ when 'developer'
+ 'write'
+ when 'reporter'
+ 'read'
+ else
+ 'read'
+ end
+ end
+
+ def validate!
+ raise Error, '该申请已经被接受' if @applied_project.accepted?
+ raise Error, '该申请不存在' unless @applied_project.present?
+ raise Error, '未拥有接受申请权限' unless is_permit_operator
+ end
+
+ def is_permit_operator
+ return @user.admin? || @project.manager?(@user)
+ end
+
+ def update_apply
+ @applied_project.update!(status: 'accepted')
+ end
+
+ def operate_project_member
+ Projects::AddMemberInteractor.call(@project.owner, @project, @applied_project.user, permission)
+ end
+
+ def send_apply_message
+ SendJoinProjectAppliedMessageJob.perform_now(@applied_project, @user, 'successed')
+ end
+end
\ No newline at end of file
diff --git a/app/services/projects/apply_join_service.rb b/app/services/projects/apply_join_service.rb
index 0b57712d0..677ee20c1 100644
--- a/app/services/projects/apply_join_service.rb
+++ b/app/services/projects/apply_join_service.rb
@@ -9,26 +9,25 @@ class Projects::ApplyJoinService < ApplicationService
end
def call
- validate!
# 项目报告人员直接加入项目
- if params[:role] == 'reporter'
- # Projects::JoinService.call(project, user, role: 'reporter')
- return project
- end
+ # if params[:role] == 'reporter'
+ # # Projects::JoinService.call(project, user, role: 'reporter')
+ # return project
+ # end
ActiveRecord::Base.transaction do
+ validate!
apply = user.applied_projects.create!(project: project, role: role_value)
+ apply
+ # apply.forge_activities.find_or_create_by!(user: user, project: project)
- apply.forge_activities.find_or_create_by!(user: user, project: project)
-
- notify_project_manager!(apply)
+ # notify_project_manager!(apply)
end
# notify_project_owner
- ApplyJoinProjectNotifyJob.perform_later(user.id, project.id, role_value)
+ # ApplyJoinProjectNotifyJob.perform_later(user.id, project.id, role_value)
- project
end
private
@@ -43,7 +42,8 @@ class Projects::ApplyJoinService < ApplicationService
when 'manager' then 3
when 'developer' then 4
when 'reporter' then 5
- else raise Error, '角色无效'
+ else
+ 5
end
end
@@ -74,12 +74,18 @@ class Projects::ApplyJoinService < ApplicationService
def validate!
# params check
raise Error, '邀请码不能为空' if params[:code].blank?
- raise Error, '角色不能为空' if params[:role].blank?
- raise Error, '角色无效' unless %w(manager developer reporter).include?(params[:role])
+ raise Error, '请输入6位项目邀请码' unless valid_invite_code( params[:code])
# logical check
raise Error, '邀请码无效' if project.blank?
- raise Error, '您已在该项目中' if project.member?(user)
- raise Error, '您已经提交过申请' if user.applied_projects.pending.exists?(project: project)
+ raise Error, '您已是项目成员' if project.member?(user)
+ raise Error, '您已经提交过申请' if user.applied_projects.common.exists?(project: project)
+ end
+
+ def valid_invite_code(str)
+ if (str =~ /^[A-Za-z0-9]{6}+$/)
+ return true
+ end
+ return false
end
end
\ No newline at end of file
diff --git a/app/services/projects/refuse_join_service.rb b/app/services/projects/refuse_join_service.rb
new file mode 100644
index 000000000..f9452586c
--- /dev/null
+++ b/app/services/projects/refuse_join_service.rb
@@ -0,0 +1,39 @@
+class Projects::RefuseJoinService < ApplicationService
+ attr_accessor :applied_project, :owner
+ attr_reader :user, :project
+
+ def initialize(user, applied_project)
+ @user = user
+ @project = applied_project.project
+ @applied_project = applied_project
+ end
+
+ def call
+ Rails.logger.info("###### Project refuse_join_service begin ######")
+ validate!
+ update_apply
+ send_apply_message
+ Rails.logger.info("###### Project refuse_join_service end ######")
+
+ return @applied_project
+ end
+
+ private
+ def validate!
+ raise Error, '该申请已被拒绝' if @applied_project.refused?
+ raise Error, '该申请不存在' unless @applied_project.present?
+ raise Error, '未拥有接受申请权限' unless is_permit_operator
+ end
+
+ def is_permit_operator
+ return @user.admin? || @project.manager?(@user)
+ end
+
+ def update_apply
+ @applied_project.update!(status: 'refused')
+ end
+
+ def send_apply_message
+ SendJoinProjectAppliedMessageJob.perform_now(@applied_project, @user, 'failure')
+ end
+end
\ No newline at end of file
diff --git a/app/views/admins/shared/_sidebar.html.erb b/app/views/admins/shared/_sidebar.html.erb
index db19e3f0e..30aa94af6 100644
--- a/app/views/admins/shared/_sidebar.html.erb
+++ b/app/views/admins/shared/_sidebar.html.erb
@@ -42,8 +42,11 @@
<% end %>
-->
- <%= sidebar_item('/admins/sidekiq', '定时任务', icon: 'bell', controller: 'root') %>
+ <%= sidebar_item('/admins/sidekiq', '定时任务', icon: 'bell', controller: 'root') %>
+
+ <%= render_admin_statistics_item %>
+
<%= sidebar_item('/', '返回主站', icon: 'sign-out', controller: 'root') %>
diff --git a/app/views/applied_projects/_detail.json.jbuilder b/app/views/applied_projects/_detail.json.jbuilder
new file mode 100644
index 000000000..e76875dc2
--- /dev/null
+++ b/app/views/applied_projects/_detail.json.jbuilder
@@ -0,0 +1,19 @@
+project = object.project
+json.project do
+ json.id project.id
+ json.identifier project.identifier
+ json.name project.name
+ json.description project.description
+ json.is_public project.is_public
+ json.owner do
+ json.partial! "/users/user_simple", locals: {user: project.owner}
+ end
+end
+json.user do
+ json.partial! "/users/user_simple", locals: {user: object.user}
+end
+json.id object.id
+json.status object.status
+json.role object.role
+json.created_at format_time(object.created_at)
+json.time_ago time_from_now(object.created_at)
diff --git a/app/views/applied_projects/create.json.jbuilder b/app/views/applied_projects/create.json.jbuilder
new file mode 100644
index 000000000..e2512880c
--- /dev/null
+++ b/app/views/applied_projects/create.json.jbuilder
@@ -0,0 +1 @@
+json.partial! "detail", locals: {object: @applied_project}
diff --git a/app/views/issues/index.json.jbuilder b/app/views/issues/index.json.jbuilder
index 13b68eb69..0f778fafe 100644
--- a/app/views/issues/index.json.jbuilder
+++ b/app/views/issues/index.json.jbuilder
@@ -1,9 +1,9 @@
json.partial! "commons/success"
-json.all_count @all_issues_size
-json.open_count @open_issues_size
-json.close_count @close_issues_size
-json.assign_me_count @assign_to_me_size
-json.my_published_count @my_published_size
+json.all_count @all_issues.size
+json.open_count @open_issues.size
+json.close_count @close_issues.size
+json.assign_me_count @assign_to_me.size
+json.my_published_count @my_published.size
json.search_count @issues_size
json.limit @limit
json.user_admin_or_member @user_admin_or_member
diff --git a/app/views/pull_requests/index.json.jbuilder b/app/views/pull_requests/index.json.jbuilder
index 14454d70d..e13f10058 100644
--- a/app/views/pull_requests/index.json.jbuilder
+++ b/app/views/pull_requests/index.json.jbuilder
@@ -1,8 +1,7 @@
json.partial! "commons/success"
-json.all_count @all_issues_size
-json.open_count @open_issues_size
-json.close_count @close_issues_size
-json.merged_issues_size @merged_issues_size
+json.open_count @open_issues.size
+json.close_count @close_issues.size
+json.merged_issues_size @merged_issues.size
json.search_count @issues_size
json.limit @limit
json.user_admin_or_member @user_admin_or_member
diff --git a/app/views/repositories/detail.json.jbuilder b/app/views/repositories/detail.json.jbuilder
index 3cf3858d6..c00ae3462 100644
--- a/app/views/repositories/detail.json.jbuilder
+++ b/app/views/repositories/detail.json.jbuilder
@@ -7,17 +7,18 @@ else
json.readme @result[:readme].merge(content: readme_render_decode64_content(@result[:readme]["content"], nil))
end
json.identifier render_identifier(@project)
+json.invite_code @project.invite_code
json.name @project.name
json.description @project.description
json.project_id @project.id
json.repo_id @repository.id
-json.issues_count @project.issues_count.to_i - @project.pull_requests_count.to_i
-json.pull_requests_count @project.pull_requests_count
+json.issues_count @project.issues.issue_issue.size - @project.issues.issue_issue.closed.size
+json.pull_requests_count @project.pull_requests.opening.size
json.project_identifier render_identifier(@project)
json.praises_count @project.praises_count.to_i
json.forked_count @project.forked_count.to_i
json.watchers_count @project.watchers_count.to_i
-json.versions_count @project.versions_count #里程碑数量
+json.versions_count @project.versions.opening.size #里程碑数量
json.version_releases_count @project.releases_size(@user.try(:id), "all")
json.version_releasesed_count @project.releases_size(@user.try(:id), "released") #已发行的版本
json.permission render_permission(@user, @project)
@@ -42,6 +43,7 @@ json.fork_info do
json.fork_project_user_login @fork_project_user.try(:login)
json.fork_project_identifier @fork_project.identifier
json.fork_project_user_name @fork_project_user.try(:show_real_name)
+ json.fork_project_user_type @fork_project_user.try(:type)
end
end
if @result[:repo]
diff --git a/app/views/users/applied_messages/_detail.json.jbuilder b/app/views/users/applied_messages/_detail.json.jbuilder
index cca202c10..796d0387f 100644
--- a/app/views/users/applied_messages/_detail.json.jbuilder
+++ b/app/views/users/applied_messages/_detail.json.jbuilder
@@ -13,7 +13,12 @@
# json.partial! "/users/user_simple", locals: {user: object.user}
# end
json.applied do
- json.partial! "/projects/applied_transfer_projects/detail", locals: {object: object.applied}
+ case object.applied_type
+ when 'AppliedTransferProject'
+ json.partial! "/projects/applied_transfer_projects/detail", locals: {object: object.applied}
+ when 'AppliedProject'
+ json.partial! "/applied_projects/detail", locals: {object: object.applied}
+ end
end
json.applied_user do
json.partial! "/users/user_simple", locals: {user: object.applied_user}
diff --git a/app/views/users/applied_projects/accept.json.jbuilder b/app/views/users/applied_projects/accept.json.jbuilder
new file mode 100644
index 000000000..d13d24bed
--- /dev/null
+++ b/app/views/users/applied_projects/accept.json.jbuilder
@@ -0,0 +1 @@
+json.partial! "/applied_projects/detail", locals: {object: @applied_project}
diff --git a/app/views/users/applied_projects/index.json.jbuilder b/app/views/users/applied_projects/index.json.jbuilder
new file mode 100644
index 000000000..6e1a1a02b
--- /dev/null
+++ b/app/views/users/applied_projects/index.json.jbuilder
@@ -0,0 +1,4 @@
+json.total_count @applied_projects.total_count
+json.applied_projects @applied_projects do |apply|
+ json.partial! "/applied_projects/detail", locals: {object: apply}
+end
diff --git a/app/views/users/applied_projects/refuse.json.jbuilder b/app/views/users/applied_projects/refuse.json.jbuilder
new file mode 100644
index 000000000..d13d24bed
--- /dev/null
+++ b/app/views/users/applied_projects/refuse.json.jbuilder
@@ -0,0 +1 @@
+json.partial! "/applied_projects/detail", locals: {object: @applied_project}
diff --git a/app/views/users/show.json.jbuilder b/app/views/users/show.json.jbuilder
index 860acb0ff..1c9e7793f 100644
--- a/app/views/users/show.json.jbuilder
+++ b/app/views/users/show.json.jbuilder
@@ -1,6 +1,7 @@
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_join_projects @common_applied_projects.size
json.undo_events @undo_events
json.user_composes_count @user_composes_count
json.user_org_count @user_org_count
diff --git a/config/routes.rb b/config/routes.rb
index 9796f774e..5a883fcb1 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -148,6 +148,8 @@ Rails.application.routes.draw do
resources :issue_depends, only: [:create, :destroy]
end
+ resources :applied_projects, only: [:create]
+
resources :project_categories, only: [:index, :show] do
get :group_list, on: :collection
end
@@ -266,6 +268,12 @@ Rails.application.routes.draw do
post :refuse
end
end
+ resources :applied_projects, only: [:index] do
+ member do
+ post :accept
+ post :refuse
+ end
+ end
resources :headmaps, only: [:index]
resources :is_pinned_projects, only: [:index, :update] do
collection do
diff --git a/db/migrate/20210609072904_add_timestamp_to_applied_projects.rb b/db/migrate/20210609072904_add_timestamp_to_applied_projects.rb
new file mode 100644
index 000000000..d5d4067a8
--- /dev/null
+++ b/db/migrate/20210609072904_add_timestamp_to_applied_projects.rb
@@ -0,0 +1,5 @@
+class AddTimestampToAppliedProjects < ActiveRecord::Migration[5.2]
+ def change
+ add_timestamps(:applied_projects, null: true)
+ end
+end
diff --git a/db/migrate/20210615063727_add_invite_code_index_to_projects.rb b/db/migrate/20210615063727_add_invite_code_index_to_projects.rb
new file mode 100644
index 000000000..398643cf9
--- /dev/null
+++ b/db/migrate/20210615063727_add_invite_code_index_to_projects.rb
@@ -0,0 +1,8 @@
+class AddInviteCodeIndexToProjects < ActiveRecord::Migration[5.2]
+ def change
+ add_index :projects, :invite_code
+ execute <<-SQL
+ ALTER TABLE projects MODIFY COLUMN invite_code VARCHAR(255) BINARY CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL;
+ SQL
+ end
+end
diff --git a/db/migrate/20210617081433_create_forge_repeat_tables.rb b/db/migrate/20210617081433_create_forge_repeat_tables.rb
new file mode 100644
index 000000000..798df39e1
--- /dev/null
+++ b/db/migrate/20210617081433_create_forge_repeat_tables.rb
@@ -0,0 +1,25 @@
+class CreateForgeRepeatTables < ActiveRecord::Migration[5.2]
+ def change
+ create_table :forge_applied_messages do |t|
+ t.references :user
+ t.references :applied, polymorphic: true
+ t.integer :viewed, default: 0
+ t.integer :status , default: 0
+ t.string :name
+ t.references :applied_user
+ t.integer :role
+ t.references :project
+
+ t.timestamps
+ end
+
+ create_table :forge_applied_projects do |t|
+ t.references :project
+ t.references :user
+ t.integer :role, default: 0
+ t.integer :status, default: 0
+
+ t.timestamps
+ end
+ end
+end
diff --git a/public/docs/api.html b/public/docs/api.html
index 0cf007cf1..5061a1ac2 100644
--- a/public/docs/api.html
+++ b/public/docs/api.html
@@ -373,11 +373,23 @@
用户拒绝迁移
+
+ 待办事项-项目申请
+
+
+ 用户接受申请
+
+
+ 用户拒绝申请
+
Projects
+ -
+ 申请加入项目
+
-
获取项目列表
@@ -617,7 +629,7 @@ Success — a happy kitten is an authenticated kitten!
Users
获取当前登陆用户信息
@@ -2016,29 +2028,29 @@ Success — a happy kitten is an authenticated kitten!
通知主体的迁移创建者头像 |
-| applied.owner.id |
+applied_user.id |
int |
-通知主体的迁移接受者的id |
+通知发起者的id |
-| applied.owner.type |
+applied_user.type |
string |
-通知主体的迁移接受者的类型 |
+通知发起者的类型 |
-| applied.owner.name |
+applied_user.name |
string |
-通知主体的迁移接受者的名称 |
+通知发起者的名称 |
-| applied.owner.login |
+applied_user.login |
string |
-通知主体的迁移接受者的标识 |
+通知发起者的标识 |
-| applied.owner.image_url |
+applied_user.image_url |
string |
-通知主体的迁移接受者头像 |
+通知发起者头像 |
| applied_type |
@@ -2073,6 +2085,48 @@ Success — a happy kitten is an authenticated kitten!
{
"total_count": 5,
"applied_messages": [
+ {
+ "applied": {
+ "project": {
+ "id": 74,
+ "identifier": "hehuisssjssjjsjs",
+ "name": "hehuisssjssjjsjs",
+ "description": "wwww",
+ "is_public": false,
+ "owner": {
+ "id": 10,
+ "type": "User",
+ "name": "testforge1",
+ "login": "testforge1",
+ "image_url": "system/lets/letter_avatars/2/T/19_237_174/120.png"
+ }
+ },
+ "user": {
+ "id": 6,
+ "type": "User",
+ "name": "何慧",
+ "login": "yystopf",
+ "image_url": "images/avatars/User/6?t=1622513134"
+ },
+ "id": 6,
+ "status": "accepted",
+ "created_at": "2021-06-09 16:34",
+ "time_ago": "1分钟前"
+ },
+ "applied_user": {
+ "id": 6,
+ "type": "User",
+ "name": "何慧",
+ "login": "yystopf",
+ "image_url": "images/avatars/User/6?t=1622513134"
+ },
+ "applied_type": "AppliedProject",
+ "name": "已通过你加入【hehuisssjssjjsjs】仓库的申请。",
+ "viewed": "waiting",
+ "status": "successed",
+ "created_at": "2021-06-09 16:34",
+ "time_ago": "1分钟前"
+ },
{
"applied": {
"project": {
@@ -2699,87 +2753,177 @@ Success — a happy kitten is an authenticated kitten!
"created_at": "2021-04-25 18:06",
"time_ago": "16小时前"
}
-
Projects
获取项目列表
-获取项目列表,也可以更加相关条件过滤搜素
+待办事项-项目申请
+待办事项-项目申请
示例:
-curl -X GET \
--d "page=1" \
--d "limit=5" \
-http://localhost:3000/api/projects | jq
-
await octokit.request('GET /api/projects')
-
HTTP 请求
-GET api/projects
-请求参数
+curl -X GET http://localhost:3000/api/users/yystopf/applied_projects.json
+
await octokit.request('GET /api/users/:login/applied_projects.json')
+
HTTP 请求
+GET /api/users/:login/applied_projects.json
+请求字段说明:
| 参数 |
-必选 |
-默认 |
类型 |
字段说明 |
-| page |
-false |
-1 |
+login |
string |
-页数,第几页 |
+用户标识 |
+
+返回字段说明:
+
-| limit |
-false |
-15 |
+参数 |
+类型 |
+字段说明 |
+
+
+
+| id |
+int |
+申请id |
+
+
+| status |
string |
-每页多少条数据,默认15条 |
+申请状态,canceled:取消,common:正在申请, accept:已接受,refuse:已拒绝 |
-| sort_by |
-false |
- |
+time_ago |
string |
-排序类型, 取值:updated_on、created_on、forked_count、praises_count; updated_on: 更新时间排序,created_on: 创建时间排序,forked_count: fork数据排序,praises_count: 点赞数量排序,默认为updated_on更新时间排序 |
+申请创建的时间 |
-| sort_direction |
-false |
- |
+project.id |
+int |
+申请项目的id |
+
+
+| project.identifier |
string |
-排序方式,取值为: desc、asc; desc: 降序排序, asc: 升序排序, 默认为:desc |
+申请项目的标识 |
-| search |
-false |
- |
+project.name |
string |
-按照项目名称搜索 |
+申请项目的名称 |
-| category_id |
-false |
- |
-int |
-项目类别id |
+project.description |
+string |
+申请项目的描述 |
-| language_id |
-false |
- |
+project.is_public |
+bool |
+申请项目是否公开 |
+
+
+| project.owner.id |
+bool |
+申请项目拥有者id |
+
+
+| project.owner.type |
+string |
+申请项目拥有者类型 |
+
+
+| project.owner.name |
+string |
+申请项目拥有者昵称 |
+
+
+| project.owner.login |
+string |
+申请项目拥有者标识 |
+
+
+| project.owner.image_url |
+string |
+申请项目拥有者头像 |
+
+
+| user.id |
int |
-项目语言id |
+申请创建者的id |
-| project_type |
-false |
- |
+user.type |
string |
-项目类型, 取值为:common、mirror; common:开源托管项目, mirror:开源镜像项目 |
+申请创建者的类型 |
+
+
+| user.name |
+string |
+申请创建者的名称 |
+
+
+| user.login |
+string |
+申请创建者的标识 |
+
+
+| user.image_url |
+string |
+申请创建者头像 |
-返回字段说明
+
+
+返回的JSON示例:
+
+{
+ "total_count": 4,
+ "applied_transfer_projects": [
+ {
+ "project": {
+ "id": 74,
+ "identifier": "hehuisssjssjjsjs",
+ "name": "hehuisssjssjjsjs",
+ "description": "wwww",
+ "is_public": false,
+ "owner": {
+ "id": 10,
+ "type": "User",
+ "name": "testforge1",
+ "login": "testforge1",
+ "image_url": "system/lets/letter_avatars/2/T/19_237_174/120.png"
+ }
+ },
+ "user": {
+ "id": 6,
+ "type": "User",
+ "name": "何慧",
+ "login": "yystopf",
+ "image_url": "images/avatars/User/6?t=1622513134"
+ },
+ "id": 7,
+ "status": "common",
+ "created_at": "2021-06-09 16:41",
+ "time_ago": "7分钟前"
+ },
+ ...
+ ]
+}
+
用户接受申请
+用户接受申请
+
+
+示例:
+
+curl -X POST http://localhost:3000/api/users/yystopf/applied_projects/2/accept.json
+
await octokit.request('GET /api/users/:login/applied_projects/:id/accept.json')
+
HTTP 请求
+GET /api/users/:login/applied_projects/:id/accept.json
+请求字段说明:
| 参数 |
@@ -2788,94 +2932,113 @@ http://localhost:3000/api/projects | jq
-| total_count |
+login |
+string |
+用户标识 |
+
+
+| id |
int |
-项目总条数 |
+申请id |
+
+
+返回字段说明:
+
+
+| 参数 |
+类型 |
+字段说明 |
+
| id |
-string |
-项目id |
+int |
+申请id |
-| name |
+status |
string |
-项目名称 |
+申请状态,canceled:取消,common:正在申请, accept:已接受,refuse:已拒绝 |
-| description |
+time_ago |
string |
-项目简介 |
+申请创建的时间 |
-| visits |
+project.id |
int |
-流量数 |
+申请项目的id |
-| forked_count |
-int |
-被fork的数量 |
+project.identifier |
+string |
+申请项目的标识 |
-| praises_count |
-int |
-star数量 |
+project.name |
+string |
+申请项目的名称 |
-| is_public |
-boolean |
-是否公开, true:公开,false:未公开 |
+project.description |
+string |
+申请项目的描述 |
-| mirror_url |
-string |
-镜像url |
+project.is_public |
+bool |
+申请项目是否公开 |
-| last_update_time |
-int |
-最后更新时间,为UNIX格式的时间戳 |
+project.owner.id |
+bool |
+申请项目拥有者id |
-| author |
-object |
-项目创建者 |
+project.owner.type |
+string |
+申请项目拥有者类型 |
-| -- name |
+project.owner.name |
string |
-用户名,也是用户标识 |
+申请项目拥有者昵称 |
-| category |
-object |
-项目类别 |
+project.owner.login |
+string |
+申请项目拥有者标识 |
-| -- id |
+project.owner.image_url |
+string |
+申请项目拥有者头像 |
+
+
+| user.id |
int |
-项目类型id |
+申请创建者的id |
-| -- name |
+user.type |
string |
-项目类型名称 |
+申请创建者的类型 |
-| language |
-object |
-项目语言 |
+user.name |
+string |
+申请创建者的名称 |
-| -- id |
-int |
-项目语言id |
+user.login |
+string |
+申请创建者的标识 |
-| -- name |
+user.image_url |
string |
-项目语言名称 |
+申请创建者头像 |
@@ -2883,10 +3046,554 @@ http://localhost:3000/api/projects | jq
返回的JSON示例:
{
- "total_count": 3096,
- "projects": [
- {
- "id": 1400794,
+ "project": {
+ "id": 74,
+ "identifier": "hehuisssjssjjsjs",
+ "name": "hehuisssjssjjsjs",
+ "description": "wwww",
+ "is_public": false,
+ "owner": {
+ "id": 10,
+ "type": "User",
+ "name": "testforge1",
+ "login": "testforge1",
+ "image_url": "system/lets/letter_avatars/2/T/19_237_174/120.png"
+ }
+ },
+ "user": {
+ "id": 6,
+ "type": "User",
+ "name": "何慧",
+ "login": "yystopf",
+ "image_url": "images/avatars/User/6?t=1622513134"
+ },
+ "id": 7,
+ "status": "accept",
+ "created_at": "2021-06-09 16:41",
+ "time_ago": "7分钟前"
+}
+
用户拒绝申请
+用户拒绝申请
+
+
+示例:
+
+curl -X POST http://localhost:3000/api/users/yystopf/applied_projects/2/refuse.json
+
await octokit.request('GET /api/users/:login/applied_projects/:id/refuse.json')
+
HTTP 请求
+GET /api/users/:login/applied_projects/:id/refuse.json
+请求字段说明:
+
+
+| 参数 |
+类型 |
+字段说明 |
+
+
+
+| login |
+string |
+用户标识 |
+
+
+| id |
+int |
+申请id |
+
+
+返回字段说明:
+
+
+| 参数 |
+类型 |
+字段说明 |
+
+
+
+| id |
+int |
+申请id |
+
+
+| status |
+string |
+申请状态,canceled:取消,common:正在申请, accept:已接受,refuse:已拒绝 |
+
+
+| time_ago |
+string |
+申请创建的时间 |
+
+
+| project.id |
+int |
+申请项目的id |
+
+
+| project.identifier |
+string |
+申请项目的标识 |
+
+
+| project.name |
+string |
+申请项目的名称 |
+
+
+| project.description |
+string |
+申请项目的描述 |
+
+
+| project.is_public |
+bool |
+申请项目是否公开 |
+
+
+| project.owner.id |
+bool |
+申请项目拥有者id |
+
+
+| project.owner.type |
+string |
+申请项目拥有者类型 |
+
+
+| project.owner.name |
+string |
+申请项目拥有者昵称 |
+
+
+| project.owner.login |
+string |
+申请项目拥有者标识 |
+
+
+| project.owner.image_url |
+string |
+申请项目拥有者头像 |
+
+
+| user.id |
+int |
+申请创建者的id |
+
+
+| user.type |
+string |
+申请创建者的类型 |
+
+
+| user.name |
+string |
+申请创建者的名称 |
+
+
+| user.login |
+string |
+申请创建者的标识 |
+
+
+| user.image_url |
+string |
+申请创建者头像 |
+
+
+
+
+返回的JSON示例:
+
+{
+ "project": {
+ "id": 74,
+ "identifier": "hehuisssjssjjsjs",
+ "name": "hehuisssjssjjsjs",
+ "description": "wwww",
+ "is_public": false,
+ "owner": {
+ "id": 10,
+ "type": "User",
+ "name": "testforge1",
+ "login": "testforge1",
+ "image_url": "system/lets/letter_avatars/2/T/19_237_174/120.png"
+ }
+ },
+ "user": {
+ "id": 6,
+ "type": "User",
+ "name": "何慧",
+ "login": "yystopf",
+ "image_url": "images/avatars/User/6?t=1622513134"
+ },
+ "id": 7,
+ "status": "accept",
+ "created_at": "2021-06-09 16:41",
+ "time_ago": "7分钟前"
+}
+
Projects
申请加入项目
+申请加入项目
+
+
+示例:
+
+curl -X POST http://localhost:3000/api/applied_projects.json
+
await octokit.request('POST /api/appliedr_projects.json')
+
HTTP 请求
+POST /api/applied_projects.json
+请求参数
+
+
+| 参数 |
+必选 |
+默认 |
+类型 |
+字段说明 |
+
+
+
+| applied_project.code |
+是 |
+ |
+string |
+邀请码 |
+
+
+| applied_project.role |
+否 |
+ |
+string |
+项目权限,reporter: 报告者, developer: 开发者,manager:管理员 |
+
+
+
+
+请求的JSON示例
+
+{
+ "applied_project": {
+ "code": "1una34",
+ "role": "developer"
+ }
+}
+
返回字段说明
+
+
+| 参数 |
+类型 |
+字段说明 |
+
+
+
+| id |
+int |
+申请id |
+
+
+| status |
+string |
+申请状态,canceled:取消,common:正在申请, accept:已接受,refuse:已拒绝 |
+
+
+| time_ago |
+string |
+项目申请创建的时间 |
+
+
+| project.id |
+int |
+申请项目的id |
+
+
+| project.identifier |
+string |
+申请项目的标识 |
+
+
+| project.name |
+string |
+申请项目的名称 |
+
+
+| project.description |
+string |
+申请项目的描述 |
+
+
+| project.is_public |
+bool |
+申请项目是否公开 |
+
+
+| project.owner.id |
+bool |
+申请项目拥有者id |
+
+
+| project.owner.type |
+string |
+申请项目拥有者类型 |
+
+
+| project.owner.name |
+string |
+申请项目拥有者昵称 |
+
+
+| project.owner.login |
+string |
+申请项目拥有者标识 |
+
+
+| project.owner.image_url |
+string |
+申请项目拥有者头像 |
+
+
+| user.id |
+int |
+申请创建者的id |
+
+
+| user.type |
+string |
+申请创建者的类型 |
+
+
+| user.name |
+string |
+申请创建者的名称 |
+
+
+| user.login |
+string |
+申请创建者的标识 |
+
+
+| user.image_url |
+string |
+申请创建者头像 |
+
+
+
+
+返回的JSON示例:
+
+{
+ "project": {
+ "id": 74,
+ "identifier": "hehuisssjssjjsjs",
+ "name": "hehuisssjssjjsjs",
+ "description": "wwww",
+ "is_public": false,
+ "owner": {
+ "id": 10,
+ "type": "User",
+ "name": "testforge1",
+ "login": "testforge1",
+ "image_url": "system/lets/letter_avatars/2/T/19_237_174/120.png"
+ }
+ },
+ "user": {
+ "id": 6,
+ "type": "User",
+ "name": "何慧",
+ "login": "yystopf",
+ "image_url": "images/avatars/User/6?t=1622513134"
+ },
+ "id": 7,
+ "status": "common",
+ "created_at": "2021-06-09 16:41",
+ "time_ago": "1分钟前"
+}
+
获取项目列表
+获取项目列表,也可以更加相关条件过滤搜素
+
+
+示例:
+
+curl -X GET \
+-d "page=1" \
+-d "limit=5" \
+http://localhost:3000/api/projects | jq
+
await octokit.request('GET /api/projects')
+
HTTP 请求
+GET api/projects
+请求参数
+
+
+| 参数 |
+必选 |
+默认 |
+类型 |
+字段说明 |
+
+
+
+| page |
+false |
+1 |
+string |
+页数,第几页 |
+
+
+| limit |
+false |
+15 |
+string |
+每页多少条数据,默认15条 |
+
+
+| sort_by |
+false |
+ |
+string |
+排序类型, 取值:updated_on、created_on、forked_count、praises_count; updated_on: 更新时间排序,created_on: 创建时间排序,forked_count: fork数据排序,praises_count: 点赞数量排序,默认为updated_on更新时间排序 |
+
+
+| sort_direction |
+false |
+ |
+string |
+排序方式,取值为: desc、asc; desc: 降序排序, asc: 升序排序, 默认为:desc |
+
+
+| search |
+false |
+ |
+string |
+按照项目名称搜索 |
+
+
+| category_id |
+false |
+ |
+int |
+项目类别id |
+
+
+| language_id |
+false |
+ |
+int |
+项目语言id |
+
+
+| project_type |
+false |
+ |
+string |
+项目类型, 取值为:common、mirror; common:开源托管项目, mirror:开源镜像项目 |
+
+
+返回字段说明
+
+
+| 参数 |
+类型 |
+字段说明 |
+
+
+
+| total_count |
+int |
+项目总条数 |
+
+
+| id |
+string |
+项目id |
+
+
+| name |
+string |
+项目名称 |
+
+
+| description |
+string |
+项目简介 |
+
+
+| visits |
+int |
+流量数 |
+
+
+| forked_count |
+int |
+被fork的数量 |
+
+
+| praises_count |
+int |
+star数量 |
+
+
+| is_public |
+boolean |
+是否公开, true:公开,false:未公开 |
+
+
+| mirror_url |
+string |
+镜像url |
+
+
+| last_update_time |
+int |
+最后更新时间,为UNIX格式的时间戳 |
+
+
+| author |
+object |
+项目创建者 |
+
+
+| -- name |
+string |
+用户名,也是用户标识 |
+
+
+| category |
+object |
+项目类别 |
+
+
+| -- id |
+int |
+项目类型id |
+
+
+| -- name |
+string |
+项目类型名称 |
+
+
+| language |
+object |
+项目语言 |
+
+
+| -- id |
+int |
+项目语言id |
+
+
+| -- name |
+string |
+项目语言名称 |
+
+
+
+
+返回的JSON示例:
+
+{
+ "total_count": 3096,
+ "projects": [
+ {
+ "id": 1400794,
"repo_id": 1402452,
"identifier": "cscw_2021_sponsor",
"name": "Sponsor机制下的开源贡献",
@@ -2931,9 +3638,9 @@ Remember — a happy kitten is an authenticated kitten!
curl -X GET \
http://localhost:3000/api/projects/recommend | jq
await octokit.request('GET /api/projects/recommend.json')
-
HTTP 请求
+
HTTP 请求
GET api/projects/recommend
-返回字段说明
+返回字段说明
| 参数 |
@@ -3067,9 +3774,9 @@ Remember — a happy kitten is an authenticated kitten!
curl -X GET \
http://localhost:3000/api/yystopf/ceshi/menu_list | jq
await octokit.request('GET /api/yystopf/ceshi/menu_list')
-
HTTP 请求
+HTTP 请求
GET api/:owner/:repo/menu_list
-请求参数
+请求参数
| 参数 |
@@ -3094,7 +3801,7 @@ http://localhost:3000/api/yystopf/ceshi/menu_list | jq
项目标识identifier |
-返回字段说明
+返回字段说明
| 参数 |
@@ -3135,9 +3842,9 @@ http://localhost:3000/api/yystopf/ceshi/menu_list | jq
curl -X GET \
http://localhost:3000/api/jasder/forgeplus/about | jq
await octokit.request('GET /api/jasder/forgeplus/about')
-
HTTP 请求
+HTTP 请求
GET api/:owner/:repo/about
-请求参数
+请求参数
| 参数 |
@@ -3162,7 +3869,7 @@ http://localhost:3000/api/jasder/forgeplus/about | jq
项目标识identifier |
-返回字段说明
+返回字段说明
| 参数 |
@@ -3208,7 +3915,7 @@ Remember — a happy kitten is an authenticated kitten!
curl -X GET \
http://localhost:3000/api/yystopf/ceshi/project_units.json
await octokit.request('GET /api/yystopf/ceshi/project_units')
-
HTTP 请求
+HTTP 请求
GET /api/yystopf/ceshi/project_units
返回字段说明:
@@ -3251,9 +3958,9 @@ http://localhost:3000/api/yystopf/ceshi/project_units.json
-d "{ \"unit_typs\": [\"code\", \"pulls\"]}" \
http://localhost:3000/api/yystopf/ceshi/project_units.json
await octokit.request('POST /api/yystopf/ceshi/project_units')
-
HTTP 请求
+HTTP 请求
POST /api/yystopf/ceshi/project_units
-请求参数
+请求参数
| 参数 |
@@ -3315,9 +4022,9 @@ http://localhost:3000/api/yystopf/ceshi/project_units.json
-d "license_id=1" \
http://localhost:3000/api/projects.json
await octokit.request('GET /api/projects.json')
-
HTTP 请求
+HTTP 请求
POST api/projects
-请求参数
+请求参数
| 参数 |
@@ -3391,7 +4098,7 @@ http://localhost:3000/api/projects.json
项目是否私有, true:为私有,false: 公开,默认为公开 |
-返回字段说明
+返回字段说明
| 参数 |
@@ -3433,9 +4140,9 @@ http://localhost:3000/api/projects.json
-d "project_language_id=2" \
http://localhost:3000/api/projects/migrate.json
await octokit.request('GET /api/projects/migrate.json')
-
HTTP 请求
+HTTP 请求
POST api/projects/migrate.json
-请求参数
+请求参数
| 参数 |
@@ -3523,7 +4230,7 @@ http://localhost:3000/api/projects/migrate.json
项目是否私有, true:为私有,false: 非私有,默认为公开 |
-返回字段说明
+返回字段说明
| 参数 |
@@ -3558,9 +4265,9 @@ http://localhost:3000/api/projects/migrate.json
curl -X POST http://localhost:3000/api/repositories/1244/sync_mirror.json
await octokit.request('POST /api/repositories/1244/sync_mirror.json')
-
HTTP 请求
+HTTP 请求
POST api/repositories/:id/sync_mirror.json
-请求参数
+请求参数
| 参数 |
@@ -3578,7 +4285,7 @@ http://localhost:3000/api/projects/migrate.json
仓库id |
-返回字段说明
+返回字段说明
| 参数 |
@@ -3613,9 +4320,9 @@ http://localhost:3000/api/projects/migrate.json
curl -X POST http://localhost:3000/api/jasder/forgeplus/forks.json
await octokit.request('POST /api/jaser/jasder_test/forks.json')
-
HTTP 请求
+HTTP 请求
POST api/:owner/:repo/forks.json
-请求参数
+请求参数
| 参数 |
@@ -3640,7 +4347,7 @@ http://localhost:3000/api/projects/migrate.json
项目标识identifier |
-返回字段说明
+返回字段说明
| 参数 |
@@ -3676,9 +4383,9 @@ http://localhost:3000/api/projects/migrate.json
curl -X GET \
http://localhost:3000/api/ceshi1/ceshi_repo1/applied_transfer_projects/organizations.json | jq
await octokit.request('GET /api/:owner/:repo/applied_transfer_projects/organizations')
-
HTTP 请求
+HTTP 请求
GET api/:owner/:repo/applied_transfer_projects/organizations
-请求参数
+请求参数
| 参数 |
@@ -3703,7 +4410,7 @@ http://localhost:3000/api/ceshi1/ceshi_repo1/applied_transfer_projects/organizat
项目标识identifier |
-返回字段说明
+返回字段说明
| 参数 |
@@ -3770,9 +4477,9 @@ http://localhost:3000/api/ceshi1/ceshi_repo1/applied_transfer_projects/organizat
curl -X POST http://localhost:3000/api/ceshi1/ceshi_repo1/applied_transfer_projects.json
await octokit.request('POST /api/:owner/:repo/applied_transfer_projects.json')
-
HTTP 请求
+HTTP 请求
POST /api/:owner/:repo/applied_transfer_projects.json
-请求参数
+请求参数
| 参数 |
@@ -3804,7 +4511,7 @@ http://localhost:3000/api/ceshi1/ceshi_repo1/applied_transfer_projects/organizat
迁移对象标识 |
-返回字段说明
+返回字段说明
| 参数 |
@@ -3974,9 +4681,9 @@ http://localhost:3000/api/ceshi1/ceshi_repo1/applied_transfer_projects/organizat
curl -X POST http://localhost:3000/api/ceshi1/ceshi_repo1/applied_transfer_projects/cancel.json
await octokit.request('POST /api/:owner/:repo/applied_transfer_projects/cancel.json')
-
HTTP 请求
+HTTP 请求
POST /api/:owner/:repo/applied_transfer_projects/cancel.json
-请求参数
+请求参数
| 参数 |
@@ -4001,7 +4708,7 @@ http://localhost:3000/api/ceshi1/ceshi_repo1/applied_transfer_projects/organizat
项目标识identifier |
-返回字段说明
+返回字段说明