forked from Gitlink/forgeplus
Compare commits
94 Commits
standalone
...
trustie_se
| Author | SHA1 | Date |
|---|---|---|
|
|
a9df1ca75f | |
|
|
4f63caa86c | |
|
|
96b0f2d167 | |
|
|
8e4e6fc0ac | |
|
|
75f3166ffa | |
|
|
04bf423fcb | |
|
|
51e8c9d908 | |
|
|
4304a35b80 | |
|
|
076375633a | |
|
|
dbf5e711a5 | |
|
|
4432e65683 | |
|
|
dcf44a78f0 | |
|
|
12edc620df | |
|
|
4ce03145df | |
|
|
3e04a37ece | |
|
|
78f464ccba | |
|
|
64423f1999 | |
|
|
05c3f60dab | |
|
|
0083ef33cb | |
|
|
36b68df273 | |
|
|
e1a5918c22 | |
|
|
26ae9b35df | |
|
|
8e79b43aaf | |
|
|
056c145ff8 | |
|
|
c105785105 | |
|
|
c2bd78d70d | |
|
|
d28eba6423 | |
|
|
688be1bb7d | |
|
|
df69dee282 | |
|
|
ee6404a3b3 | |
|
|
fae8313df6 | |
|
|
45a77e5c07 | |
|
|
7849bd0ebf | |
|
|
7f58b870d4 | |
|
|
0c7499842f | |
|
|
ab361d8009 | |
|
|
3649bf1fd0 | |
|
|
bcfb544cca | |
|
|
edb1114d39 | |
|
|
a24d33d2ee | |
|
|
6ffc2938a1 | |
|
|
aa60de1dac | |
|
|
29f98513e2 | |
|
|
e35cdf39fb | |
|
|
3f98e78942 | |
|
|
bec98bbc9d | |
|
|
af160084c4 | |
|
|
e51b86538b | |
|
|
da4fd3a762 | |
|
|
01e7d857c8 | |
|
|
96d1a7440d | |
|
|
8a34699acd | |
|
|
efc82b9841 | |
|
|
e3df503dd2 | |
|
|
6a2ad67386 | |
|
|
3d12db3a07 | |
|
|
9c5ff55b70 | |
|
|
82bae9159b | |
|
|
1d13b3686b | |
|
|
1faaf1d7d1 | |
|
|
f8a6f62342 | |
|
|
b816b6a449 | |
|
|
d48700d200 | |
|
|
66d1246a6c | |
|
|
f79beef3f9 | |
|
|
81e6691632 | |
|
|
38d6519381 | |
|
|
16418675ac | |
|
|
102858bc8c | |
|
|
0d64768e4b | |
|
|
beccac652f | |
|
|
30eb1958c1 | |
|
|
33e17e8439 | |
|
|
5445206716 | |
|
|
1c19c05fd8 | |
|
|
957980fc71 | |
|
|
657e2cf169 | |
|
|
e0c47c2abd | |
|
|
9e64a4842d | |
|
|
ba9e74f373 | |
|
|
93dd5b5d84 | |
|
|
422549f9e7 | |
|
|
0358229b95 | |
|
|
c4586fbb36 | |
|
|
0a5a75dc0d | |
|
|
5618887e7a | |
|
|
9a8ddffb5a | |
|
|
f889849b6b | |
|
|
b7bebcd736 | |
|
|
30135ccad7 | |
|
|
d9925db510 | |
|
|
6479ac8696 | |
|
|
f4e4015a89 | |
|
|
e25e2fdd77 |
|
|
@ -23,7 +23,7 @@
|
|||
* Fix 版本库中附件下载400(#51625)
|
||||
* Fix loading页面优化(#51588)
|
||||
* Fix 提交详情页面优化(#51577)
|
||||
* Fix 修复易修复制功能(#51569)
|
||||
* Fix 修复疑修复制功能(#51569)
|
||||
* Fix 修复新建发行版用户信息显示错误的问题(#51665)
|
||||
* Fix 修复查看文件详细信息报错的问题(#51561)
|
||||
* Fix 修复提交记录中时间显示格式问题(#51526)
|
||||
|
|
@ -62,7 +62,7 @@
|
|||
## [v3.0.3](https://forgeplus.trustie.net/projects/jasder/forgeplus/releases) - 2021-05-08
|
||||
|
||||
* BUGFIXES
|
||||
* Fix 解决易修标题过长导致的排版问题(45469)
|
||||
* Fix 解决疑修标题过长导致的排版问题(45469)
|
||||
* Fix 解决合并请求详情页面排版错误的问题(45457)
|
||||
* FIX 解决转移仓库界面专有名词描述错误的问题(45455)
|
||||
* Fix 解决markdown格式文件自动生成数字排序的问题(45454)
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ class AccountsController < ApplicationController
|
|||
|
||||
# 其他平台同步注册的用户
|
||||
def remote_register
|
||||
Register::RemoteForm.new(remote_register_params).validate!
|
||||
username = params[:username]&.gsub(/\s+/, "")
|
||||
tip_exception("无法使用以下关键词:#{username},请重新命名") if ReversedKeyword.check_exists?(username)
|
||||
email = params[:email]&.gsub(/\s+/, "")
|
||||
|
|
@ -375,5 +376,9 @@ class AccountsController < ApplicationController
|
|||
phone_or_mail = strip(reset_password_params[:login])
|
||||
User.where("phone = :search OR mail = :search", search: phone_or_mail).last
|
||||
end
|
||||
|
||||
def remote_register_params
|
||||
params.permit(:username, :email, :password, :platform)
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,138 @@
|
|||
#coding=utf-8
|
||||
class ClaimsController < ApplicationController
|
||||
# skip_before_action :verify_authenticity_token
|
||||
protect_from_forgery with: :null_session
|
||||
before_action :require_login, except: [:index]
|
||||
before_action :set_issue
|
||||
|
||||
def index
|
||||
@user_claimed = 0
|
||||
@claims = @issue.claims.claim_includes.order("created_at desc")
|
||||
|
||||
@claims.each do |claim|
|
||||
if claim.user_id == current_user.id
|
||||
@user_claimed = 1
|
||||
break
|
||||
end
|
||||
end
|
||||
render file: 'app/views/claims/list.json.jbuilder'
|
||||
end
|
||||
|
||||
def create
|
||||
@claim = Claim.find_by_sql(["select id from claims where issue_id=? and user_id=?",params[:issue_id], current_user.id])
|
||||
if @claim.present?
|
||||
return normal_status(-1,"您已经声明过该易修")
|
||||
end
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
@claim = Claim.new(parse_issue_params(params))
|
||||
if @claim.save
|
||||
@claims = @issue.claims.claim_includes.order("created_at desc")
|
||||
@user_claimed = 1
|
||||
|
||||
journal_params = {
|
||||
journalized_id: params[:issue_id],
|
||||
journalized_type: "Issue",
|
||||
user_id: current_user.id ,
|
||||
notes: "新建声明: #{params[:claim_note]}",
|
||||
}
|
||||
|
||||
journal = Journal.new(journal_params)
|
||||
if journal.save
|
||||
render file: 'app/views/claims/list.json.jbuilder'
|
||||
else
|
||||
normal_status(-1,"新建声明关联评论操作失败")
|
||||
end
|
||||
|
||||
else
|
||||
normal_status(-1,"新建声明操作失败")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
@claim = Claim.find_by_id(params[:claim_id])
|
||||
if @claim.blank?
|
||||
return normal_status(-1,"易修不存在")
|
||||
end
|
||||
|
||||
if @claim.user_id != current_user.id
|
||||
return normal_status(-1,"你不能更新别人的声明")
|
||||
end
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
if @claim.update_attribute(:note,params[:claim_note])
|
||||
@claims = @issue.claims.claim_includes.order("created_at desc")
|
||||
@user_claimed = 1
|
||||
|
||||
journal_params = {
|
||||
journalized_id: params[:issue_id],
|
||||
journalized_type: "Issue",
|
||||
user_id: current_user.id ,
|
||||
notes: "更新声明: #{params[:claim_note]}",
|
||||
}
|
||||
|
||||
journal = Journal.new(journal_params)
|
||||
if journal.save
|
||||
render file: 'app/views/claims/list.json.jbuilder'
|
||||
else
|
||||
normal_status(-1,"新建声明关联评论操作失败")
|
||||
end
|
||||
|
||||
else
|
||||
normal_status(-1,"声明更新操作失败")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@claim = Claim.find_by_sql(["select id from claims where issue_id=? and user_id=?",params[:issue_id], current_user.id])
|
||||
if @claim.blank?
|
||||
normal_status(-1,"您未曾声明过该易修")
|
||||
else
|
||||
@claim = @claim[0]
|
||||
# 判断current user是否是claimer
|
||||
ActiveRecord::Base.transaction do
|
||||
if @claim.destroy
|
||||
|
||||
@claims = @issue.claims.claim_includes.order("created_at desc")
|
||||
@user_claimed = 0
|
||||
|
||||
journal_params = {
|
||||
journalized_id: params[:issue_id],
|
||||
journalized_type: "Issue",
|
||||
user_id: current_user.id ,
|
||||
notes: "取消声明",
|
||||
}
|
||||
|
||||
journal = Journal.new(journal_params)
|
||||
if journal.save
|
||||
render file: 'app/views/claims/list.json.jbuilder'
|
||||
else
|
||||
normal_status(-1,"新建声明关联评论操作失败")
|
||||
end
|
||||
|
||||
else
|
||||
normal_status(-1,"取消声明操作失败")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def parse_issue_params(params)
|
||||
{
|
||||
issue_id: params[:issue_id],
|
||||
user_id: current_user.id,
|
||||
note: params[:claim_note],
|
||||
}
|
||||
end
|
||||
|
||||
def set_issue
|
||||
@issue = Issue.find_by_id(params[:issue_id])
|
||||
unless @issue.present?
|
||||
normal_status(-1, "易修不存在")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -42,12 +42,14 @@ class CompareController < ApplicationController
|
|||
end
|
||||
|
||||
def load_compare_params
|
||||
@base = Addressable::URI.unescape(params[:base])
|
||||
# @base = Addressable::URI.unescape(params[:base])
|
||||
@base = Base64.decode64(params[:base])
|
||||
@head = params[:head].include?('.json') ? params[:head][0..-6] : params[:head]
|
||||
|
||||
# @head = Addressable::URI.unescape(@head)
|
||||
@head = Base64.decode64(@head)
|
||||
end
|
||||
|
||||
def gitea_compare(base, head)
|
||||
Gitea::Repository::Commits::CompareService.call(@owner.login, @project.identifier, base, head, current_user.gitea_token)
|
||||
Gitea::Repository::Commits::CompareService.call(@owner.login, @project.identifier, CGI.escape(base), CGI.escape(head), current_user.gitea_token)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -486,7 +486,8 @@ class IssuesController < ApplicationController
|
|||
end
|
||||
|
||||
def operate_issue_permission
|
||||
return render_forbidden("您没有权限进行此操作.") unless current_user.present? && current_user.logged? && (current_user.admin? || @project.member?(current_user) || @project.is_public?)
|
||||
@issue = Issue.find_by_id(params[:id]) unless @issue.present?
|
||||
return render_forbidden("您没有权限进行此操作.") unless current_user.present? && current_user.logged? && (current_user.admin? || @project.member?(current_user) || (@project.is_public && @issue.nil?) || (@project.is_public && @issue.present? && @issue.author_id == current_user.id))
|
||||
end
|
||||
|
||||
def export_issues(issues)
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ class Organizations::OrganizationsController < Organizations::BaseController
|
|||
def create
|
||||
ActiveRecord::Base.transaction do
|
||||
tip_exception("无法使用以下关键词:#{organization_params[:name]},请重新命名") if ReversedKeyword.check_exists?(organization_params[:name])
|
||||
Organizations::CreateForm.new(organization_params).validate!
|
||||
Organizations::CreateForm.new(organization_params.merge(original_name: "")).validate!
|
||||
@organization = Organizations::CreateService.call(current_user, organization_params)
|
||||
Util.write_file(@image, avatar_path(@organization)) if params[:image].present?
|
||||
end
|
||||
|
|
@ -39,7 +39,7 @@ class Organizations::OrganizationsController < Organizations::BaseController
|
|||
|
||||
def update
|
||||
ActiveRecord::Base.transaction do
|
||||
Organizations::CreateForm.new(organization_params).validate!
|
||||
Organizations::CreateForm.new(organization_params.merge(original_name: @organization.login)).validate!
|
||||
login = @organization.login
|
||||
@organization.login = organization_params[:name] if organization_params[:name].present?
|
||||
@organization.nickname = organization_params[:nickname] if organization_params[:nickname].present?
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ class Organizations::TeamUsersController < Organizations::BaseController
|
|||
ActiveRecord::Base.transaction do
|
||||
@team_user = TeamUser.build(@organization.id, @operate_user.id, @team.id)
|
||||
@organization_user = OrganizationUser.build(@organization.id, @operate_user.id)
|
||||
SendTemplateMessageJob.perform_later('OrganizationRole', @operate_user.id, @organization.id, @team.authorize_name) if Site.has_notice_menu?
|
||||
SendTemplateMessageJob.perform_later('TeamJoined', @operate_user.id, @organization.id, @team.id) if Site.has_notice_menu?
|
||||
Gitea::Organization::TeamUser::CreateService.call(@organization.gitea_token, @team.gtid, @operate_user.login)
|
||||
end
|
||||
rescue Exception => e
|
||||
|
|
@ -31,6 +31,7 @@ class Organizations::TeamUsersController < Organizations::BaseController
|
|||
ActiveRecord::Base.transaction do
|
||||
@team_user.destroy!
|
||||
Gitea::Organization::TeamUser::DeleteService.call(@organization.gitea_token, @team.gtid, @operate_user.login)
|
||||
SendTemplateMessageJob.perform_later('TeamLeft', @operate_user.id, @organization.id, @team.id) if Site.has_notice_menu?
|
||||
org_team_users = @organization.team_users.where(user_id: @operate_user.id)
|
||||
unless org_team_users.present?
|
||||
@organization.organization_users.find_by(user_id: @operate_user.id).destroy!
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ class ProjectTrendsController < ApplicationController
|
|||
before_action :check_project_public
|
||||
|
||||
def index
|
||||
project_trends = @project.project_trends.preload(:user, trend: :user)
|
||||
project_trends = @project.project_trends.preload(:user, trend: :user, project: :owner)
|
||||
|
||||
check_time = params[:time] #时间的筛选
|
||||
check_type = params[:type] #动态类型的筛选,目前已知的有 Issue, PullRequest, Version
|
||||
|
|
|
|||
|
|
@ -16,13 +16,13 @@ class ProjectsController < ApplicationController
|
|||
menu.append(menu_hash_by_name("home"))
|
||||
menu.append(menu_hash_by_name("code")) if @project.has_menu_permission("code")
|
||||
menu.append(menu_hash_by_name("issues")) if @project.has_menu_permission("issues")
|
||||
menu.append(menu_hash_by_name("pulls")) if @project.has_menu_permission("pulls")
|
||||
menu.append(menu_hash_by_name("wiki")) if @project.has_menu_permission("wiki")
|
||||
menu.append(menu_hash_by_name("devops")) if @project.has_menu_permission("devops")
|
||||
menu.append(menu_hash_by_name("pulls")) if @project.has_menu_permission("pulls") && @project.forge?
|
||||
menu.append(menu_hash_by_name("devops")) if @project.has_menu_permission("devops") && @project.forge?
|
||||
menu.append(menu_hash_by_name("versions")) if @project.has_menu_permission("versions")
|
||||
menu.append(menu_hash_by_name("resources")) if @project.has_menu_permission("resources")
|
||||
menu.append(menu_hash_by_name("wiki")) if @project.has_menu_permission("wiki") && @project.forge?
|
||||
menu.append(menu_hash_by_name("resources")) if @project.has_menu_permission("resources") && @project.forge?
|
||||
menu.append(menu_hash_by_name("activity"))
|
||||
menu.append(menu_hash_by_name("settings")) if current_user.admin? || @project.manager?(current_user)
|
||||
menu.append(menu_hash_by_name("settings")) if (current_user.admin? || @project.manager?(current_user)) && @project.forge?
|
||||
|
||||
render json: menu
|
||||
end
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ class PullRequestsController < ApplicationController
|
|||
end
|
||||
|
||||
def create
|
||||
return normal_status(-1, "您不是目标分支开发者,没有权限,请联系目标分支作者.") unless @project.operator?(current_user)
|
||||
# return normal_status(-1, "您不是目标分支开发者,没有权限,请联系目标分支作者.") unless @project.operator?(current_user)
|
||||
ActiveRecord::Base.transaction do
|
||||
@pull_request, @gitea_pull_request = PullRequests::CreateService.call(current_user, @owner, @project, params)
|
||||
if @gitea_pull_request[:status] == :success
|
||||
|
|
@ -89,6 +89,7 @@ class PullRequestsController < ApplicationController
|
|||
else
|
||||
ActiveRecord::Base.transaction do
|
||||
begin
|
||||
return normal_status(-1, "title不能超过255个字符") if params[:title].length > 255
|
||||
merge_params
|
||||
|
||||
@issue&.issue_tags_relates&.destroy_all if params[:issue_tag_ids].blank?
|
||||
|
|
|
|||
|
|
@ -1,368 +1,387 @@
|
|||
class RepositoriesController < ApplicationController
|
||||
include RepositoriesHelper
|
||||
include ApplicationHelper
|
||||
include OperateProjectAbilityAble
|
||||
include Repository::LanguagesPercentagable
|
||||
|
||||
before_action :require_login, only: %i[edit update create_file update_file delete_file sync_mirror]
|
||||
before_action :require_profile_completed, only: [:create_file]
|
||||
before_action :load_repository
|
||||
before_action :authorizate!, except: [:sync_mirror, :tags, :commit, :archive]
|
||||
before_action :authorizate_user_can_edit_repo!, only: %i[sync_mirror]
|
||||
before_action :get_ref, only: %i[entries sub_entries top_counts file archive]
|
||||
before_action :get_latest_commit, only: %i[entries sub_entries top_counts]
|
||||
before_action :get_statistics, only: %i[top_counts]
|
||||
|
||||
def files
|
||||
result = @project.educoder? ? nil : Gitea::Repository::Files::GetService.call(@owner, @project.identifier, @ref, params[:search], @owner.gitea_token)
|
||||
render json: result
|
||||
end
|
||||
|
||||
# 新版项目详情
|
||||
def detail
|
||||
@user = current_user
|
||||
@result = Repositories::DetailService.call(@owner, @repository, @user)
|
||||
@project_fork_id = @project.try(:forked_from_project_id)
|
||||
if @project_fork_id.present?
|
||||
@fork_project = Project.find_by(id: @project_fork_id)
|
||||
@fork_project_user = @fork_project.owner
|
||||
end
|
||||
rescue Exception => e
|
||||
uid_logger_error(e.message)
|
||||
tip_exception(e.message)
|
||||
end
|
||||
|
||||
def show
|
||||
@user = current_user
|
||||
@repo = @project.repository
|
||||
@result = @project.forge? ? Gitea::Repository::GetService.new(@owner, @project.identifier).call : nil
|
||||
@project_fork_id = @project.try(:forked_from_project_id)
|
||||
if @project_fork_id.present?
|
||||
@fork_project = Project.find_by(id: @project_fork_id)
|
||||
@fork_project_user = @fork_project.owner
|
||||
end
|
||||
rescue Exception => e
|
||||
uid_logger_error(e.message)
|
||||
tip_exception(e.message)
|
||||
end
|
||||
|
||||
def entries
|
||||
@project.increment!(:visits)
|
||||
CacheAsyncSetJob.perform_later("project_common_service", {visits: 1}, @project.id)
|
||||
if @project.educoder?
|
||||
@entries = Educoder::Repository::Entries::ListService.call(@project&.project_educoder.repo_name)
|
||||
else
|
||||
@entries = Gitea::Repository::Entries::ListService.new(@owner, @project.identifier, ref: @ref).call
|
||||
@entries = @entries.present? ? @entries.sort_by{ |hash| hash['type'] } : []
|
||||
@path = Gitea.gitea_config[:domain]+"/#{@project.owner.login}/#{@project.identifier}/raw/branch/#{@ref}/"
|
||||
end
|
||||
end
|
||||
|
||||
def top_counts
|
||||
@result = @project.educoder? ? nil : Gitea::Repository::GetService.new(@project.owner, @project.identifier).call
|
||||
end
|
||||
|
||||
def sub_entries
|
||||
file_path_uri = URI.parse(URI.encode(params[:filepath].to_s.strip))
|
||||
|
||||
if @project.educoder?
|
||||
if params[:type] === 'file'
|
||||
@sub_entries = Educoder::Repository::Entries::GetService.call(@project&.project_educoder&.repo_name, file_path_uri)
|
||||
logger.info "######### sub_entries: #{@sub_entries}"
|
||||
return render_error('该文件暂未开放,敬请期待.') if @sub_entries['status'].to_i === -1
|
||||
|
||||
tmp_entries = [{
|
||||
"content" => @sub_entries['data']['content'],
|
||||
"type" => "blob"
|
||||
}]
|
||||
@sub_entries = {
|
||||
"trees"=>tmp_entries,
|
||||
"commits" => [{}]
|
||||
}
|
||||
else
|
||||
@sub_entries = Educoder::Repository::Entries::ListService.call(@project&.project_educoder&.repo_name, {path: file_path_uri})
|
||||
end
|
||||
else
|
||||
@path = Gitea.gitea_config[:domain]+"/#{@project.owner.login}/#{@project.identifier}/raw/branch/#{@ref}/"
|
||||
interactor = Repositories::EntriesInteractor.call(@owner, @project.identifier, file_path_uri, ref: @ref)
|
||||
if interactor.success?
|
||||
result = interactor.result
|
||||
@sub_entries = result.is_a?(Array) ? result.sort_by{ |hash| hash['type'] } : result
|
||||
else
|
||||
render_error(interactor.error)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def commits
|
||||
if @project.educoder?
|
||||
@hash_commit = nil
|
||||
else
|
||||
if params[:filepath].present?
|
||||
file_path_uri = URI.parse(URI.encode(params[:filepath].to_s.strip))
|
||||
@hash_commit = Gitea::Repository::Commits::FileListService.new(@owner.login, @project.identifier, file_path_uri,
|
||||
sha: params[:sha], page: params[:page], limit: params[:limit], token: current_user&.gitea_token).call
|
||||
else
|
||||
@hash_commit = Gitea::Repository::Commits::ListService.new(@owner.login, @project.identifier,
|
||||
sha: params[:sha], page: params[:page], limit: params[:limit], token: current_user&.gitea_token).call
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def commits_slice
|
||||
@hash_commit = Gitea::Repository::Commits::ListSliceService.call(@owner&.login, @project.identifier,
|
||||
sha: params[:sha], page: params[:page], limit: params[:limit], token: current_user&.gitea_token)
|
||||
end
|
||||
|
||||
def commit
|
||||
@sha = params[:sha]
|
||||
if @project.educoder?
|
||||
@commit = {}
|
||||
@commit_diff ={}
|
||||
else
|
||||
@commit = Gitea::Repository::Commits::GetService.call(@owner.login, @repository.identifier, @sha, current_user&.gitea_token)
|
||||
@commit_diff = Gitea::Repository::Commits::GetService.call(@owner.login, @repository.identifier, @sha, current_user&.gitea_token, {diff: true})
|
||||
end
|
||||
end
|
||||
|
||||
def tags
|
||||
result = Gitea::Repository::Tags::ListService.call(current_user&.gitea_token, @owner.login, @project.identifier, {page: params[:page], limit: params[:limit]})
|
||||
|
||||
@tags = result.is_a?(Hash) && result.key?(:status) ? [] : result
|
||||
end
|
||||
|
||||
def contributors
|
||||
if params[:filepath].present?
|
||||
@contributors = []
|
||||
else
|
||||
@contributors = Gitea::Repository::Contributors::GetService.call(@owner, @repository.identifier)
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
return render_forbidden if !@project.manager?(current_user) && !current_user.admin?
|
||||
end
|
||||
|
||||
def create_file
|
||||
interactor = Gitea::CreateFileInteractor.call(current_user.gitea_token, @owner.login, content_params)
|
||||
if interactor.success?
|
||||
@file = interactor.result
|
||||
# create_new_pr(params)
|
||||
#如果是更新流水线文件
|
||||
if params[:pipeline_id]
|
||||
update_pipeline(params[:pipeline_id])
|
||||
end
|
||||
else
|
||||
render_error(interactor.error)
|
||||
end
|
||||
end
|
||||
|
||||
def update_pipeline(pipeline_id)
|
||||
pipeline = Ci::Pipeline.find(pipeline_id)
|
||||
if pipeline
|
||||
pipeline.update!(sync: 1)
|
||||
end
|
||||
end
|
||||
|
||||
def update_file
|
||||
interactor = Gitea::UpdateFileInteractor.call(current_user.gitea_token, @owner.login, params.merge(identifier: @project.identifier))
|
||||
if interactor.success?
|
||||
@file = interactor.result
|
||||
# TODO: 是否创建pr
|
||||
# create_new_pr(params)
|
||||
render_result(1, "更新成功")
|
||||
else
|
||||
render_error(interactor.error)
|
||||
end
|
||||
end
|
||||
|
||||
def delete_file
|
||||
interactor = Gitea::DeleteFileInteractor.call(current_user.gitea_token, @owner.login, params.merge(identifier: @project.identifier))
|
||||
if interactor.success?
|
||||
@file = interactor.result
|
||||
render_result(1, "文件删除成功")
|
||||
else
|
||||
render_error(interactor.error)
|
||||
end
|
||||
end
|
||||
|
||||
def repo_hook
|
||||
|
||||
end
|
||||
|
||||
def sync_mirror
|
||||
return render_error("正在镜像中..") if @repository.mirror.waiting?
|
||||
|
||||
@repository.sync_mirror!
|
||||
SyncMirroredRepositoryJob.perform_later(@repository.id, current_user.id)
|
||||
render_ok
|
||||
end
|
||||
|
||||
def readme
|
||||
if params[:filepath].present?
|
||||
result = Gitea::Repository::Readme::DirService.call(@owner.login, @repository.identifier, params[:filepath], params[:ref], current_user&.gitea_token)
|
||||
else
|
||||
result = Gitea::Repository::Readme::GetService.call(@owner.login, @repository.identifier, params[:ref], current_user&.gitea_token)
|
||||
end
|
||||
@path = Gitea.gitea_config[:domain]+"/#{@owner.login}/#{@repository.identifier}/raw/branch/#{params[:ref]}/"
|
||||
@readme = result[:status] === :success ? result[:body] : nil
|
||||
@readme['content'] = decode64_content(@readme, @owner, @repository, params[:ref], @path)
|
||||
render json: @readme.slice("type", "encoding", "size", "name", "path", "content", "sha")
|
||||
rescue
|
||||
render json: nil
|
||||
end
|
||||
|
||||
def languages
|
||||
render json: languages_precentagable
|
||||
end
|
||||
|
||||
def archive
|
||||
domain = Gitea.gitea_config[:domain]
|
||||
api_url = Gitea.gitea_config[:base_url]
|
||||
archive_url = "/repos/#{@owner.login}/#{@repository.identifier}/archive/#{params[:archive]}"
|
||||
|
||||
file_path = [domain, api_url, archive_url].join
|
||||
file_path = [file_path, "access_token=#{current_user&.gitea_token}"].join("?") if @repository.hidden?
|
||||
|
||||
return render_not_found if !request.format.zip? && !request.format.gzip?
|
||||
|
||||
redirect_to file_path
|
||||
end
|
||||
|
||||
def raw
|
||||
domain = Gitea.gitea_config[:domain]
|
||||
api_url = Gitea.gitea_config[:base_url]
|
||||
|
||||
url = "/repos/#{@owner.login}/#{@repository.identifier}/raw/#{params[:filepath]}?ref=#{params[:ref]}"
|
||||
file_path = [domain, api_url, url].join
|
||||
file_path = [file_path, "access_token=#{current_user&.gitea_token}"].join("&") if @repository.hidden?
|
||||
|
||||
redirect_to URI.escape(file_path)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_project
|
||||
@project = Project.find params[:id]
|
||||
render_not_found("未找到相关的仓库") unless @project
|
||||
end
|
||||
|
||||
def find_project_with_includes
|
||||
@project = Project.includes(:repository, :owner, :watchers, :praise_treads).find params[:id]
|
||||
end
|
||||
|
||||
def authorizate!
|
||||
return if current_user && current_user.admin?
|
||||
if @project.repository.hidden? && !@project.member?(current_user)
|
||||
render_forbidden
|
||||
end
|
||||
end
|
||||
|
||||
# TODO 获取最新commit信息
|
||||
def project_commits
|
||||
if params[:filepath].present?
|
||||
file_path_uri = URI.parse(URI.encode(params[:filepath].to_s.strip))
|
||||
Gitea::Repository::Commits::FileListService.new(@project.owner.login, @project.identifier, file_path_uri,
|
||||
sha: get_ref, page: 1, limit: 1, token: current_user&.gitea_token).call
|
||||
else
|
||||
Gitea::Repository::Commits::ListService.new(@project.owner.login, @project.identifier,
|
||||
sha: get_ref, page: 1, limit: 1, token: current_user&.gitea_token).call
|
||||
end
|
||||
end
|
||||
|
||||
def get_statistics
|
||||
@branches_count = @project.educoder? ? 0 : Gitea::Repository::Branches::ListService.new(@project.owner, @project.identifier).call&.size
|
||||
@tags_count = @project.educoder? ? 0 : Gitea::Repository::Tags::ListService.new(current_user&.gitea_token, @project.owner.login, @project.identifier).call&.size
|
||||
end
|
||||
|
||||
def get_ref
|
||||
@ref = params[:ref] || @project&.default_branch
|
||||
end
|
||||
|
||||
def get_latest_commit
|
||||
latest_commit = @project.educoder? ? nil : project_commits
|
||||
@latest_commit = latest_commit.present? ? latest_commit[:body][0] : nil
|
||||
@commits_count = latest_commit.present? ? latest_commit[:total_count] : 0
|
||||
end
|
||||
|
||||
def content_params
|
||||
{
|
||||
filepath: params[:filepath],
|
||||
branch: params[:branch],
|
||||
new_branch: params[:new_branch],
|
||||
content: params[:content],
|
||||
message: params[:message],
|
||||
committer: {
|
||||
email: current_user.mail,
|
||||
name: current_user.login
|
||||
},
|
||||
identifier: @project.identifier
|
||||
}
|
||||
end
|
||||
|
||||
def hook_params(hook_type, params)
|
||||
# if hook_type == "push"
|
||||
# # TODO hook返回的记录中,暂时没有文件代码数量的增减,暂时根据 commits数量来计算
|
||||
# uploadPushInfo = {
|
||||
# "sha": params["commits"].present? ? params["commits"].last : "",
|
||||
# "branch": params["ref"].to_s.split("/").last,
|
||||
# "modification_lines": params["commits"].length
|
||||
# }
|
||||
# elsif hook_type == "pull_request" && params["action"].to_s == "closed" #合并请求合并后才会有上链操作
|
||||
# uploadPushInfo = {
|
||||
# "branch": params["base"]["ref"].to_s.split("/").last,
|
||||
# "sha": params["pull_request"]["merge_base"],
|
||||
# "modification_lines": 1 #pull_request中没有commits数量
|
||||
# }
|
||||
# else
|
||||
# uploadPushInfo = {}
|
||||
# end
|
||||
|
||||
# uploadPushInfo
|
||||
end
|
||||
|
||||
def create_new_pr(params)
|
||||
if params[:new_branch].present? && params[:new_branch] != params[:branch]
|
||||
local_params = {
|
||||
title: params[:message], #标题
|
||||
body: params[:content], #内容
|
||||
head: params[:new_branch], #源分支
|
||||
base: params[:branch], #目标分支
|
||||
milestone: 0 #里程碑,未与本地的里程碑关联
|
||||
|
||||
}
|
||||
requests_params = local_params.merge({
|
||||
assignee: current_user.try(:login),
|
||||
assignees: [],
|
||||
labels: [],
|
||||
due_date: Time.now
|
||||
})
|
||||
|
||||
issue_params = {
|
||||
author_id: current_user.id,
|
||||
project_id: @project.id,
|
||||
subject: params[:message],
|
||||
description: params[:content],
|
||||
assigned_to_id: nil,
|
||||
fixed_version_id: nil,
|
||||
issue_tags_value: nil,
|
||||
issue_classify: "pull_request",
|
||||
issue_type: "1",
|
||||
tracker_id: 2,
|
||||
status_id: 1,
|
||||
priority_id: params[:priority_id] || "2"
|
||||
}
|
||||
@pull_issue = Issue.new(issue_params)
|
||||
if @pull_issue.save!
|
||||
local_requests = PullRequest.new(local_params.merge(user_id: current_user.try(:id), project_id: @project.id, issue_id: @pull_issue.id))
|
||||
if local_requests.save
|
||||
gitea_request = Gitea::PullRequest::CreateService.new(current_user.try(:gitea_token), @owner.login, @project.try(:identifier), requests_params).call
|
||||
if gitea_request[:status] == :success && local_requests.update_attributes(gitea_number: gitea_request["body"]["number"], gpid: gitea_request["body"]["number"])
|
||||
local_requests.project_trends.create(user_id: current_user.id, project_id: @project.id, action_type: "create")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
class RepositoriesController < ApplicationController
|
||||
include RepositoriesHelper
|
||||
include ApplicationHelper
|
||||
include OperateProjectAbilityAble
|
||||
include Repository::LanguagesPercentagable
|
||||
|
||||
before_action :require_login, only: %i[edit update create_file update_file delete_file sync_mirror]
|
||||
before_action :require_profile_completed, only: [:create_file]
|
||||
before_action :load_repository
|
||||
before_action :authorizate!, except: [:sync_mirror, :tags, :commit, :archive]
|
||||
before_action :authorizate_user_can_edit_repo!, only: %i[sync_mirror]
|
||||
before_action :get_ref, only: %i[entries sub_entries top_counts file archive]
|
||||
before_action :get_latest_commit, only: %i[entries sub_entries top_counts]
|
||||
before_action :get_statistics, only: %i[top_counts]
|
||||
|
||||
def files
|
||||
result = @project.educoder? ? nil : Gitea::Repository::Files::GetService.call(@owner, @project.identifier, @ref, params[:search], @owner.gitea_token)
|
||||
render json: result
|
||||
end
|
||||
|
||||
# 新版项目详情
|
||||
def detail
|
||||
@user = current_user
|
||||
@result = Repositories::DetailService.call(@owner, @repository, @user)
|
||||
@project_fork_id = @project.try(:forked_from_project_id)
|
||||
if @project_fork_id.present?
|
||||
@fork_project = Project.find_by(id: @project_fork_id)
|
||||
@fork_project_user = @fork_project.owner
|
||||
end
|
||||
rescue Exception => e
|
||||
uid_logger_error(e.message)
|
||||
tip_exception(e.message)
|
||||
end
|
||||
|
||||
def show
|
||||
@user = current_user
|
||||
@repo = @project.repository
|
||||
@result = @project.forge? ? Gitea::Repository::GetService.new(@owner, @project.identifier).call : nil
|
||||
@project_fork_id = @project.try(:forked_from_project_id)
|
||||
if @project_fork_id.present?
|
||||
@fork_project = Project.find_by(id: @project_fork_id)
|
||||
@fork_project_user = @fork_project.owner
|
||||
end
|
||||
rescue Exception => e
|
||||
uid_logger_error(e.message)
|
||||
tip_exception(e.message)
|
||||
end
|
||||
|
||||
def entries
|
||||
@project.increment!(:visits)
|
||||
CacheAsyncSetJob.perform_later("project_common_service", {visits: 1}, @project.id)
|
||||
if @project.educoder?
|
||||
@entries = Educoder::Repository::Entries::ListService.call(@project&.project_educoder.repo_name)
|
||||
else
|
||||
@entries = Gitea::Repository::Entries::ListService.new(@owner, @project.identifier, ref: @ref).call
|
||||
@entries = @entries.present? ? @entries.sort_by{ |hash| hash['type'] } : []
|
||||
@path = Gitea.gitea_config[:domain]+"/#{@project.owner.login}/#{@project.identifier}/raw/branch/#{@ref}/"
|
||||
end
|
||||
end
|
||||
|
||||
def top_counts
|
||||
@result = @project.educoder? ? nil : Gitea::Repository::GetService.new(@project.owner, @project.identifier).call
|
||||
end
|
||||
|
||||
def sub_entries
|
||||
file_path_uri = URI.parse(URI.encode(params[:filepath].to_s.strip))
|
||||
|
||||
if @project.educoder?
|
||||
if params[:type] === 'file'
|
||||
@sub_entries = Educoder::Repository::Entries::GetService.call(@project&.project_educoder&.repo_name, file_path_uri)
|
||||
logger.info "######### sub_entries: #{@sub_entries}"
|
||||
return render_error('该文件暂未开放,敬请期待.') if @sub_entries['status'].to_i === -1
|
||||
|
||||
tmp_entries = {
|
||||
"content" => @sub_entries['data']['content'],
|
||||
"type" => "blob"
|
||||
}
|
||||
@sub_entries = {
|
||||
"trees"=>tmp_entries,
|
||||
"commits" => [{}]
|
||||
}
|
||||
else
|
||||
begin
|
||||
@sub_entries = Educoder::Repository::Entries::ListService.call(@project&.project_educoder&.repo_name, {path: file_path_uri})
|
||||
if @sub_entries.blank? || @sub_entries['status'].to_i === -1
|
||||
@sub_entries = Educoder::Repository::Entries::GetService.call(@project&.project_educoder&.repo_name, file_path_uri)
|
||||
return render_error('该文件暂未开放,敬请期待.') if @sub_entries['status'].to_i === -1
|
||||
tmp_entries = {
|
||||
"content" => @sub_entries['data']['content'],
|
||||
"type" => "blob"
|
||||
}
|
||||
@sub_entries = {
|
||||
"trees"=>tmp_entries,
|
||||
"commits" => [{}]
|
||||
}
|
||||
end
|
||||
rescue
|
||||
return render_error('该文件暂未开放,敬请期待.')
|
||||
end
|
||||
end
|
||||
else
|
||||
@path = Gitea.gitea_config[:domain]+"/#{@project.owner.login}/#{@project.identifier}/raw/branch/#{@ref}/"
|
||||
interactor = Repositories::EntriesInteractor.call(@owner, @project.identifier, file_path_uri, ref: @ref)
|
||||
if interactor.success?
|
||||
result = interactor.result
|
||||
@sub_entries = result.is_a?(Array) ? result.sort_by{ |hash| hash['type'] } : result
|
||||
else
|
||||
render_error(interactor.error)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def commits
|
||||
if @project.educoder?
|
||||
@commits = Educoder::Repository::Commits::ListService.call(@project&.project_educoder&.repo_name)
|
||||
else
|
||||
if params[:filepath].present?
|
||||
file_path_uri = URI.parse(URI.encode(params[:filepath].to_s.strip))
|
||||
@hash_commit = Gitea::Repository::Commits::FileListService.new(@owner.login, @project.identifier, file_path_uri,
|
||||
sha: params[:sha], page: params[:page], limit: params[:limit], token: current_user&.gitea_token).call
|
||||
else
|
||||
@hash_commit = Gitea::Repository::Commits::ListService.new(@owner.login, @project.identifier,
|
||||
sha: params[:sha], page: params[:page], limit: params[:limit], token: current_user&.gitea_token).call
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def commits_slice
|
||||
@hash_commit = Gitea::Repository::Commits::ListSliceService.call(@owner.login, @project.identifier,
|
||||
sha: params[:sha], page: params[:page], limit: params[:limit], token: current_user&.gitea_token)
|
||||
end
|
||||
|
||||
def commit
|
||||
@sha = params[:sha]
|
||||
if @project.educoder?
|
||||
return render_error('暂未开放,敬请期待.')
|
||||
else
|
||||
@commit = Gitea::Repository::Commits::GetService.call(@owner.login, @repository.identifier, @sha, current_user&.gitea_token)
|
||||
@commit_diff = Gitea::Repository::Commits::GetService.call(@owner.login, @repository.identifier, @sha, current_user&.gitea_token, {diff: true})
|
||||
end
|
||||
end
|
||||
|
||||
def tags
|
||||
result = Gitea::Repository::Tags::ListService.call(current_user&.gitea_token, @owner.login, @project.identifier, {page: params[:page], limit: params[:limit]})
|
||||
|
||||
@tags = result.is_a?(Hash) && result.key?(:status) ? [] : result
|
||||
end
|
||||
|
||||
def contributors
|
||||
if params[:filepath].present? || @project.educoder?
|
||||
@contributors = []
|
||||
else
|
||||
@contributors = Gitea::Repository::Contributors::GetService.call(@owner, @repository.identifier)
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
return render_forbidden if !@project.manager?(current_user) && !current_user.admin?
|
||||
end
|
||||
|
||||
def create_file
|
||||
interactor = Gitea::CreateFileInteractor.call(current_user.gitea_token, @owner.login, content_params)
|
||||
if interactor.success?
|
||||
@file = interactor.result
|
||||
# create_new_pr(params)
|
||||
#如果是更新流水线文件
|
||||
if params[:pipeline_id]
|
||||
update_pipeline(params[:pipeline_id])
|
||||
end
|
||||
else
|
||||
render_error(interactor.error)
|
||||
end
|
||||
end
|
||||
|
||||
def update_pipeline(pipeline_id)
|
||||
pipeline = Ci::Pipeline.find(pipeline_id)
|
||||
if pipeline
|
||||
pipeline.update!(sync: 1)
|
||||
end
|
||||
end
|
||||
|
||||
def update_file
|
||||
interactor = Gitea::UpdateFileInteractor.call(current_user.gitea_token, @owner.login, params.merge(identifier: @project.identifier))
|
||||
if interactor.success?
|
||||
@file = interactor.result
|
||||
# TODO: 是否创建pr
|
||||
# create_new_pr(params)
|
||||
render_result(1, "更新成功")
|
||||
else
|
||||
render_error(interactor.error)
|
||||
end
|
||||
end
|
||||
|
||||
def delete_file
|
||||
interactor = Gitea::DeleteFileInteractor.call(current_user.gitea_token, @owner.login, params.merge(identifier: @project.identifier))
|
||||
if interactor.success?
|
||||
@file = interactor.result
|
||||
render_result(1, "文件删除成功")
|
||||
else
|
||||
render_error(interactor.error)
|
||||
end
|
||||
end
|
||||
|
||||
def repo_hook
|
||||
|
||||
end
|
||||
|
||||
def sync_mirror
|
||||
return render_error("正在镜像中..") if @repository.mirror.waiting?
|
||||
|
||||
@repository.sync_mirror!
|
||||
SyncMirroredRepositoryJob.perform_later(@repository.id, current_user.id)
|
||||
render_ok
|
||||
end
|
||||
|
||||
def readme
|
||||
if params[:filepath].present?
|
||||
result = Gitea::Repository::Readme::DirService.call(@owner.login, @repository.identifier, params[:filepath], params[:ref], current_user&.gitea_token)
|
||||
else
|
||||
result = Gitea::Repository::Readme::GetService.call(@owner.login, @repository.identifier, params[:ref], current_user&.gitea_token)
|
||||
end
|
||||
@path = Gitea.gitea_config[:domain]+"/#{@owner.login}/#{@repository.identifier}/raw/branch/#{params[:ref]}/"
|
||||
@readme = result[:status] === :success ? result[:body] : nil
|
||||
@readme['content'] = decode64_content(@readme, @owner, @repository, params[:ref], @path)
|
||||
render json: @readme.slice("type", "encoding", "size", "name", "path", "content", "sha")
|
||||
rescue
|
||||
render json: nil
|
||||
end
|
||||
|
||||
def languages
|
||||
if @project.educoder?
|
||||
render json: {}
|
||||
else
|
||||
render json: languages_precentagable
|
||||
end
|
||||
end
|
||||
|
||||
def archive
|
||||
domain = Gitea.gitea_config[:domain]
|
||||
api_url = Gitea.gitea_config[:base_url]
|
||||
archive_url = "/repos/#{@owner.login}/#{@repository.identifier}/archive/#{CGI.escape(params[:archive])}"
|
||||
|
||||
file_path = [domain, api_url, archive_url].join
|
||||
file_path = [file_path, "access_token=#{current_user&.gitea_token}"].join("?") if @repository.hidden?
|
||||
|
||||
return render_not_found if !request.format.zip? && !request.format.gzip?
|
||||
|
||||
redirect_to file_path
|
||||
end
|
||||
|
||||
def raw
|
||||
domain = Gitea.gitea_config[:domain]
|
||||
api_url = Gitea.gitea_config[:base_url]
|
||||
|
||||
url = "/repos/#{@owner.login}/#{@repository.identifier}/raw/#{URI.escape(params[:filepath])}?ref=#{CGI.escape(params[:ref])}"
|
||||
file_path = [domain, api_url, url].join
|
||||
file_path = [file_path, "access_token=#{current_user&.gitea_token}"].join("&")
|
||||
|
||||
redirect_to file_path
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_project
|
||||
@project = Project.find params[:id]
|
||||
render_not_found("未找到相关的仓库") unless @project
|
||||
end
|
||||
|
||||
def find_project_with_includes
|
||||
@project = Project.includes(:repository, :owner, :watchers, :praise_treads).find params[:id]
|
||||
end
|
||||
|
||||
def authorizate!
|
||||
return if current_user && current_user.admin?
|
||||
if @project.repository.hidden? && !@project.member?(current_user)
|
||||
render_forbidden
|
||||
end
|
||||
end
|
||||
|
||||
# TODO 获取最新commit信息
|
||||
def project_commits
|
||||
if params[:filepath].present?
|
||||
file_path_uri = URI.parse(URI.encode(params[:filepath].to_s.strip))
|
||||
Gitea::Repository::Commits::FileListService.new(@project.owner.login, @project.identifier, file_path_uri,
|
||||
sha: get_ref, page: 1, limit: 1, token: current_user&.gitea_token).call
|
||||
else
|
||||
Gitea::Repository::Commits::ListService.new(@project.owner.login, @project.identifier,
|
||||
sha: get_ref, page: 1, limit: 1, token: current_user&.gitea_token).call
|
||||
end
|
||||
end
|
||||
|
||||
def get_statistics
|
||||
@branches_count = @project.educoder? ? 0 : Gitea::Repository::Branches::ListService.new(@project.owner, @project.identifier).call&.size
|
||||
@tags_count = @project.educoder? ? 0 : Gitea::Repository::Tags::ListService.new(current_user&.gitea_token, @project.owner.login, @project.identifier).call&.size
|
||||
end
|
||||
|
||||
def get_ref
|
||||
@ref = params[:ref] || @project&.default_branch
|
||||
end
|
||||
|
||||
def get_latest_commit
|
||||
latest_commit = @project.educoder? ? nil : project_commits
|
||||
@latest_commit = latest_commit.present? ? latest_commit[:body][0] : nil
|
||||
@commits_count = latest_commit.present? ? latest_commit[:total_count] : 0
|
||||
end
|
||||
|
||||
def content_params
|
||||
{
|
||||
filepath: params[:filepath],
|
||||
branch: params[:branch],
|
||||
new_branch: params[:new_branch],
|
||||
content: params[:content],
|
||||
message: params[:message],
|
||||
committer: {
|
||||
email: current_user.mail,
|
||||
name: current_user.login
|
||||
},
|
||||
identifier: @project.identifier
|
||||
}
|
||||
end
|
||||
|
||||
def hook_params(hook_type, params)
|
||||
# if hook_type == "push"
|
||||
# # TODO hook返回的记录中,暂时没有文件代码数量的增减,暂时根据 commits数量来计算
|
||||
# uploadPushInfo = {
|
||||
# "sha": params["commits"].present? ? params["commits"].last : "",
|
||||
# "branch": params["ref"].to_s.split("/").last,
|
||||
# "modification_lines": params["commits"].length
|
||||
# }
|
||||
# elsif hook_type == "pull_request" && params["action"].to_s == "closed" #合并请求合并后才会有上链操作
|
||||
# uploadPushInfo = {
|
||||
# "branch": params["base"]["ref"].to_s.split("/").last,
|
||||
# "sha": params["pull_request"]["merge_base"],
|
||||
# "modification_lines": 1 #pull_request中没有commits数量
|
||||
# }
|
||||
# else
|
||||
# uploadPushInfo = {}
|
||||
# end
|
||||
|
||||
# uploadPushInfo
|
||||
end
|
||||
|
||||
def create_new_pr(params)
|
||||
if params[:new_branch].present? && params[:new_branch] != params[:branch]
|
||||
local_params = {
|
||||
title: params[:message], #标题
|
||||
body: params[:content], #内容
|
||||
head: params[:new_branch], #源分支
|
||||
base: params[:branch], #目标分支
|
||||
milestone: 0 #里程碑,未与本地的里程碑关联
|
||||
|
||||
}
|
||||
requests_params = local_params.merge({
|
||||
assignee: current_user.try(:login),
|
||||
assignees: [],
|
||||
labels: [],
|
||||
due_date: Time.now
|
||||
})
|
||||
|
||||
issue_params = {
|
||||
author_id: current_user.id,
|
||||
project_id: @project.id,
|
||||
subject: params[:message],
|
||||
description: params[:content],
|
||||
assigned_to_id: nil,
|
||||
fixed_version_id: nil,
|
||||
issue_tags_value: nil,
|
||||
issue_classify: "pull_request",
|
||||
issue_type: "1",
|
||||
tracker_id: 2,
|
||||
status_id: 1,
|
||||
priority_id: params[:priority_id] || "2"
|
||||
}
|
||||
@pull_issue = Issue.new(issue_params)
|
||||
if @pull_issue.save!
|
||||
local_requests = PullRequest.new(local_params.merge(user_id: current_user.try(:id), project_id: @project.id, issue_id: @pull_issue.id))
|
||||
if local_requests.save
|
||||
gitea_request = Gitea::PullRequest::CreateService.new(current_user.try(:gitea_token), @owner.login, @project.try(:identifier), requests_params).call
|
||||
if gitea_request[:status] == :success && local_requests.update_attributes(gpid: gitea_request["body"]["number"])
|
||||
local_requests.project_trends.create(user_id: current_user.id, project_id: @project.id, action_type: "create")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,852 @@
|
|||
# Projects
|
||||
|
||||
## 申请加入项目
|
||||
申请加入项目
|
||||
|
||||
> 示例:
|
||||
|
||||
```shell
|
||||
curl -X POST http://localhost:3000/api/applied_projects.json
|
||||
```
|
||||
|
||||
```javascript
|
||||
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示例
|
||||
|
||||
```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示例:
|
||||
|
||||
```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分钟前"
|
||||
}
|
||||
```
|
||||
|
||||
## 获取项目列表
|
||||
获取项目列表,也可以更加相关条件过滤搜素
|
||||
|
||||
> 示例:
|
||||
|
||||
```shell
|
||||
curl -X GET \
|
||||
-d "page=1" \
|
||||
-d "limit=5" \
|
||||
http://localhost:3000/api/projects | jq
|
||||
```
|
||||
|
||||
```javascript
|
||||
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示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"total_count": 3096,
|
||||
"projects": [
|
||||
{
|
||||
"id": 1400794,
|
||||
"repo_id": 1402452,
|
||||
"identifier": "cscw_2021_sponsor",
|
||||
"name": "Sponsor机制下的开源贡献",
|
||||
"description": "CSCW 2021 sponsor机制研究",
|
||||
"visits": 5,
|
||||
"praises_count": 0,
|
||||
"forked_count": 0,
|
||||
"is_public": true,
|
||||
"mirror_url": null,
|
||||
"type": 0,
|
||||
"last_update_time": 1611971671,
|
||||
"time_ago": "2天前",
|
||||
"forked_from_project_id": null,
|
||||
"open_devops": false,
|
||||
"platform": "forge",
|
||||
"author": {
|
||||
"name": "张迅晖",
|
||||
"login": "Nigel",
|
||||
"image_url": "images/avatars/User/3675?t=1611832880"
|
||||
},
|
||||
"category": {
|
||||
"id": 13,
|
||||
"name": "云计算和大数据"
|
||||
},
|
||||
"language": {
|
||||
"id": 34,
|
||||
"name": "Python3.6"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
<aside class="success">
|
||||
Remember — a happy kitten is an authenticated kitten!
|
||||
</aside>
|
||||
|
||||
|
||||
## 推荐项目
|
||||
获取推荐项目列表
|
||||
|
||||
> 示例:
|
||||
|
||||
```shell
|
||||
curl -X GET \
|
||||
http://localhost:3000/api/projects/recommend | jq
|
||||
```
|
||||
|
||||
```javascript
|
||||
await octokit.request('GET /api/projects/recommend.json')
|
||||
```
|
||||
|
||||
### HTTP 请求
|
||||
`GET api/projects/recommend`
|
||||
|
||||
|
||||
### 返回字段说明
|
||||
参数 | 类型 | 字段说明
|
||||
--------- | ----------- | -----------
|
||||
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示例:
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"id": 20,
|
||||
"repo_id": 2,
|
||||
"identifier": "PNAekinmH",
|
||||
"name": "FNILL",
|
||||
"visits": 13567,
|
||||
"author": {
|
||||
"name": "王一达",
|
||||
"login": "wangyida",
|
||||
"image_url": "avatars/User/b"
|
||||
},
|
||||
"category": {
|
||||
"id": 8,
|
||||
"name": "其他"
|
||||
}
|
||||
}
|
||||
]
|
||||
```
|
||||
<aside class="success">
|
||||
Remember — a happy kitten is an authenticated kitten!
|
||||
</aside>
|
||||
|
||||
|
||||
## 项目导航
|
||||
获取项目导航信息
|
||||
|
||||
> 示例:
|
||||
|
||||
```shell
|
||||
curl -X GET \
|
||||
http://localhost:3000/api/yystopf/ceshi/menu_list | jq
|
||||
```
|
||||
|
||||
```javascript
|
||||
await octokit.request('GET /api/yystopf/ceshi/menu_list')
|
||||
```
|
||||
|
||||
### HTTP 请求
|
||||
`GET api/:owner/:repo/menu_list`
|
||||
|
||||
### 请求参数
|
||||
参数 | 必选 | 默认 | 类型 | 字段说明
|
||||
--------- | ------- | ------- | -------- | ----------
|
||||
owner |是| |string |用户登录名
|
||||
repo |是| |string |项目标识identifier
|
||||
|
||||
### 返回字段说明
|
||||
参数 | 类型 | 字段说明
|
||||
--------- | ----------- | -----------
|
||||
menu_name |string|导航名称, home:主页,code:代码库,issues:疑修,pulls:合并请求,devops:工作流,versions:里程碑,activity:动态,setting:仓库设置
|
||||
|
||||
|
||||
> 返回的JSON示例:
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"menu_name": "home"
|
||||
},
|
||||
{
|
||||
"menu_name": "code"
|
||||
},
|
||||
{
|
||||
"menu_name": "pulls"
|
||||
},
|
||||
{
|
||||
"menu_name": "activity"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
|
||||
## 项目主页
|
||||
获取项目主页信息
|
||||
|
||||
> 示例:
|
||||
|
||||
```shell
|
||||
curl -X GET \
|
||||
http://localhost:3000/api/jasder/forgeplus/about | jq
|
||||
```
|
||||
|
||||
```javascript
|
||||
await octokit.request('GET /api/jasder/forgeplus/about')
|
||||
```
|
||||
|
||||
### HTTP 请求
|
||||
`GET api/:owner/:repo/about`
|
||||
|
||||
### 请求参数
|
||||
参数 | 必选 | 默认 | 类型 | 字段说明
|
||||
--------- | ------- | ------- | -------- | ----------
|
||||
owner |是| |string |用户登录名
|
||||
repo |是| |string |项目标识identifier
|
||||
|
||||
### 返回字段说明
|
||||
参数 | 类型 | 字段说明
|
||||
--------- | ----------- | -----------
|
||||
identifier |string|project's identifier
|
||||
content |string|主页内容
|
||||
attachments |array|附件
|
||||
|
||||
|
||||
> 返回的JSON示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"content": "",
|
||||
"identifier": "forgeplus",
|
||||
attachments: []
|
||||
}
|
||||
```
|
||||
<aside class="success">
|
||||
Remember — a happy kitten is an authenticated kitten!
|
||||
</aside>
|
||||
|
||||
## 项目模块信息
|
||||
项目模块信息
|
||||
|
||||
> 示例:
|
||||
|
||||
```shell
|
||||
curl -X GET \
|
||||
http://localhost:3000/api/yystopf/ceshi/project_units.json
|
||||
```
|
||||
|
||||
```javascript
|
||||
await octokit.request('GET /api/yystopf/ceshi/project_units')
|
||||
```
|
||||
|
||||
### HTTP 请求
|
||||
`GET /api/yystopf/ceshi/project_units`
|
||||
|
||||
### 返回字段说明:
|
||||
参数 | 类型 | 字段说明
|
||||
--------- | ----------- | -----------
|
||||
|type |string|模块名称 |
|
||||
|
||||
> 返回的JSON示例:
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"type": "code"
|
||||
},
|
||||
{
|
||||
"type": "pulls"
|
||||
},
|
||||
{
|
||||
"type": "issues"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## 更改项目模块展示
|
||||
更改项目模块展示
|
||||
|
||||
> 示例:
|
||||
|
||||
```shell
|
||||
curl -X POST \
|
||||
-H "accept: application/json" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{ \"unit_typs\": [\"code\", \"pulls\"]}" \
|
||||
http://localhost:3000/api/yystopf/ceshi/project_units.json
|
||||
```
|
||||
|
||||
```javascript
|
||||
await octokit.request('POST /api/yystopf/ceshi/project_units')
|
||||
```
|
||||
|
||||
### HTTP 请求
|
||||
`POST /api/yystopf/ceshi/project_units`
|
||||
|
||||
### 请求参数
|
||||
参数 | 必选 | 默认 | 类型 | 字段说明
|
||||
--------- | ------- | ------- | -------- | ----------
|
||||
|unit_types |是| |array | 项目模块内容, 支持以下参数:code:代码库,issues:疑修,pulls:合并请求,devops:工作流,versions:里程碑 |
|
||||
|
||||
|
||||
### 返回字段说明:
|
||||
参数 | 类型 | 字段说明
|
||||
--------- | ----------- | -----------
|
||||
|status |int|返回状态, 0: 表示操作成功 |
|
||||
|message |string|返回信息说明|
|
||||
|
||||
> 返回的JSON示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"status": 0,
|
||||
"message": "success"
|
||||
}
|
||||
```
|
||||
|
||||
## 创建项目
|
||||
创建项目
|
||||
|
||||
> 示例:
|
||||
|
||||
```shell
|
||||
curl -X POST \
|
||||
-d "user_id=36401" \
|
||||
-d "name=hnfl_demo" \
|
||||
-d "description=my first project" \
|
||||
-d "repository_name=hnfl_demo" \
|
||||
-d "project_category_id=1" \
|
||||
-d "project_language_id=2" \
|
||||
-d "ignore_id=2" \
|
||||
-d "license_id=1" \
|
||||
http://localhost:3000/api/projects.json
|
||||
```
|
||||
|
||||
```javascript
|
||||
await octokit.request('GET /api/projects.json')
|
||||
```
|
||||
|
||||
### HTTP 请求
|
||||
`POST api/projects`
|
||||
|
||||
### 请求参数
|
||||
参数 | 必选 | 默认 | 类型 | 字段说明
|
||||
--------- | ------- | ------- | -------- | ----------
|
||||
|user_id |是| |int |用户id或者组织id |
|
||||
|name |是| |string |项目名称 |
|
||||
|description |是| |string |项目描述 |
|
||||
|repository_name |是| |string |仓库名称, 只含有数字、字母、下划线不能以下划线开头和结尾,且唯一 |
|
||||
|project_category_id|是| |int |项目类别id |
|
||||
|project_language_id|是| |int |项目语言id |
|
||||
|ignore_id |否| |int |gitignore相关id |
|
||||
|license_id |否| |int |开源许可证id |
|
||||
|private |否| |boolean|项目是否私有, true:为私有,false: 公开,默认为公开 |
|
||||
|
||||
### 返回字段说明
|
||||
参数 | 类型 | 字段说明
|
||||
--------- | ----------- | -----------
|
||||
|id |int |id |
|
||||
|name |string|项目名称|
|
||||
|
||||
|
||||
> 返回的JSON示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 3240,
|
||||
"name": "好项目"
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## 创建镜像项目
|
||||
创建镜像项目
|
||||
|
||||
> 示例:
|
||||
|
||||
```shell
|
||||
curl -X POST \
|
||||
-d "user_id=36408" \
|
||||
-d "clone_addr=https://gitea.com/mx8090alex/golden.git" \
|
||||
-d "name=golden_mirror1" \
|
||||
-d "description=golden_mirror" \
|
||||
-d "project_category_id=1" \
|
||||
-d "project_language_id=2" \
|
||||
http://localhost:3000/api/projects/migrate.json
|
||||
```
|
||||
|
||||
```javascript
|
||||
await octokit.request('GET /api/projects/migrate.json')
|
||||
```
|
||||
|
||||
### HTTP 请求
|
||||
`POST api/projects/migrate.json`
|
||||
|
||||
### 请求参数
|
||||
参数 | 必选 | 默认 | 类型 | 字段说明
|
||||
--------- | ------- | ------- | -------- | ----------
|
||||
|user_id |是| |int |用户id或者组织id |
|
||||
|name |是| |string |项目名称 |
|
||||
|clone_addr |是| |string |镜像项目clone地址 |
|
||||
|description |否| |string |项目描述 |
|
||||
|repository_name |是| |string |仓库名称, 只含有数字、字母、下划线不能以下划线开头和结尾,且唯一 |
|
||||
|project_category_id|是| |int |项目类别id |
|
||||
|project_language_id|是| |int |项目语言id |
|
||||
|is_mirror |否| |boolean|是否设置为镜像, true:是, false:否,默认为否 |
|
||||
|auth_username |否| |string|镜像源仓库的登录用户名 |
|
||||
|auth_password |否| |string|镜像源仓库的登录秘密 |
|
||||
|private |否| |boolean|项目是否私有, true:为私有,false: 非私有,默认为公开 |
|
||||
|
||||
### 返回字段说明
|
||||
参数 | 类型 | 字段说明
|
||||
--------- | ----------- | -----------
|
||||
|id |int |id |
|
||||
|name |string|项目名称|
|
||||
|
||||
|
||||
> 返回的JSON示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 3241,
|
||||
"name": "这是一个镜像项目"
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## 同步镜像
|
||||
手动同步镜像
|
||||
|
||||
> 示例:
|
||||
|
||||
```shell
|
||||
curl -X POST http://localhost:3000/api/repositories/1244/sync_mirror.json
|
||||
```
|
||||
|
||||
```javascript
|
||||
await octokit.request('POST /api/repositories/1244/sync_mirror.json')
|
||||
```
|
||||
|
||||
### HTTP 请求
|
||||
`POST api/repositories/:id/sync_mirror.json`
|
||||
|
||||
### 请求参数
|
||||
参数 | 必选 | 默认 | 类型 | 字段说明
|
||||
--------- | ------- | ------- | -------- | ----------
|
||||
|id |是| |int |仓库id |
|
||||
|
||||
|
||||
### 返回字段说明
|
||||
参数 | 类型 | 字段说明
|
||||
--------- | ----------- | -----------
|
||||
|status |int |状态码, 0:标识请求成功 |
|
||||
|message |string|服务端返回的信息说明|
|
||||
|
||||
|
||||
> 返回的JSON示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"status": 0,
|
||||
"message": "success"
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Fork项目
|
||||
fork项目
|
||||
|
||||
> 示例:
|
||||
|
||||
```shell
|
||||
curl -X POST http://localhost:3000/api/jasder/forgeplus/forks.json
|
||||
```
|
||||
|
||||
```javascript
|
||||
await octokit.request('POST /api/jaser/jasder_test/forks.json')
|
||||
```
|
||||
|
||||
### HTTP 请求
|
||||
`POST api/:owner/:repo/forks.json`
|
||||
|
||||
### 请求参数
|
||||
参数 | 必选 | 默认 | 类型 | 字段说明
|
||||
--------- | ------- | ------- | -------- | ----------
|
||||
|owner |是| |string |用户登录名 |
|
||||
|repo |是| |string |项目标识identifier |
|
||||
|
||||
### 返回字段说明
|
||||
参数 | 类型 | 字段说明
|
||||
--------- | ----------- | -----------
|
||||
|id |int |项目id |
|
||||
|identifier |string|项目标识|
|
||||
|
||||
|
||||
> 返回的JSON示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 3290,
|
||||
"identifier": "newadm"
|
||||
}
|
||||
```
|
||||
|
||||
## 用户管理的组织列表
|
||||
用户管理的组织列表
|
||||
|
||||
> 示例:
|
||||
|
||||
```shell
|
||||
curl -X GET \
|
||||
http://localhost:3000/api/ceshi1/ceshi_repo1/applied_transfer_projects/organizations.json | jq
|
||||
```
|
||||
|
||||
```javascript
|
||||
await octokit.request('GET /api/:owner/:repo/applied_transfer_projects/organizations')
|
||||
```
|
||||
|
||||
### HTTP 请求
|
||||
`GET api/:owner/:repo/applied_transfer_projects/organizations`
|
||||
|
||||
### 请求参数
|
||||
参数 | 必选 | 默认 | 类型 | 字段说明
|
||||
--------- | ------- | ------- | -------- | ----------
|
||||
owner |是| |string |用户登录名
|
||||
repo |是| |string |项目标识identifier
|
||||
|
||||
### 返回字段说明
|
||||
参数 | 类型 | 字段说明
|
||||
--------- | ----------- | -----------
|
||||
name |string|组织标识
|
||||
nickname |string|组织名称
|
||||
description|string|组织描述
|
||||
avatar_url|string|组织头像
|
||||
|
||||
|
||||
> 返回的JSON示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"total_count": 3,
|
||||
"organizations": [
|
||||
{
|
||||
"id": 9,
|
||||
"name": "ceshi_org",
|
||||
"nickname": "测试组织",
|
||||
"description": "测试组织",
|
||||
"avatar_url": "images/avatars/Organization/9?t=1612706073"
|
||||
},
|
||||
{
|
||||
"id": 51,
|
||||
"name": "ceshi",
|
||||
"nickname": "测试组织哈哈哈",
|
||||
"description": "23212312",
|
||||
"avatar_url": "images/avatars/Organization/51?t=1618800723"
|
||||
},
|
||||
{
|
||||
"id": 52,
|
||||
"name": "ceshi1",
|
||||
"nickname": "身份卡手动阀",
|
||||
"description": "1231手动阀是的",
|
||||
"avatar_url": "images/avatars/Organization/52?t=1618805056"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 迁移项目
|
||||
迁移项目,edit接口is_transfering为true表示正在迁移
|
||||
|
||||
> 示例:
|
||||
|
||||
```shell
|
||||
curl -X POST http://localhost:3000/api/ceshi1/ceshi_repo1/applied_transfer_projects.json
|
||||
```
|
||||
|
||||
```javascript
|
||||
await octokit.request('POST /api/:owner/:repo/applied_transfer_projects.json')
|
||||
```
|
||||
|
||||
### HTTP 请求
|
||||
`POST /api/:owner/:repo/applied_transfer_projects.json`
|
||||
|
||||
### 请求参数
|
||||
参数 | 必选 | 默认 | 类型 | 字段说明
|
||||
--------- | ------- | ------- | -------- | ----------
|
||||
|owner |是| |string |用户登录名 |
|
||||
|repo |是| |string |项目标识identifier |
|
||||
|owner_name|是| |string |迁移对象标识 |
|
||||
|
||||
### 返回字段说明
|
||||
参数 | 类型 | 字段说明
|
||||
--------- | ----------- | -----------
|
||||
|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 |迁移创建者头像 |
|
||||
|owner.id |int |迁移接受者的id |
|
||||
|owner.type |string |迁移接受者的类型 |
|
||||
|owner.name |string |迁移接受者的名称 |
|
||||
|owner.login |string |迁移接受者的标识 |
|
||||
|owner.image_url |string |迁移接受者头像 |
|
||||
> 返回的JSON示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"project": {
|
||||
"id": 86,
|
||||
"identifier": "ceshi_repo1",
|
||||
"name": "测试项目啊1",
|
||||
"description": "二十多",
|
||||
"is_public": true,
|
||||
"owner": {
|
||||
"id": 52,
|
||||
"type": "Organization",
|
||||
"name": "身份卡手动阀",
|
||||
"login": "ceshi1",
|
||||
"image_url": "images/avatars/Organization/52?t=1618805056"
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"id": 6,
|
||||
"type": "User",
|
||||
"name": "yystopf",
|
||||
"login": "yystopf",
|
||||
"image_url": "system/lets/letter_avatars/2/Y/241_125_89/120.png"
|
||||
},
|
||||
"owner": {
|
||||
"id": 9,
|
||||
"type": "Organization",
|
||||
"name": "测试组织",
|
||||
"login": "ceshi_org",
|
||||
"image_url": "images/avatars/Organization/9?t=1612706073"
|
||||
},
|
||||
"id": 4,
|
||||
"status": "common",
|
||||
"created_at": "2021-04-26 09:54",
|
||||
"time_ago": "1分钟前"
|
||||
}
|
||||
```
|
||||
|
||||
## 取消迁移项目
|
||||
迁移项目,edit接口is_transfering为true表示正在迁移
|
||||
|
||||
> 示例:
|
||||
|
||||
```shell
|
||||
curl -X POST http://localhost:3000/api/ceshi1/ceshi_repo1/applied_transfer_projects/cancel.json
|
||||
```
|
||||
|
||||
```javascript
|
||||
await octokit.request('POST /api/:owner/:repo/applied_transfer_projects/cancel.json')
|
||||
```
|
||||
|
||||
### HTTP 请求
|
||||
`POST /api/:owner/:repo/applied_transfer_projects/cancel.json`
|
||||
|
||||
### 请求参数
|
||||
参数 | 必选 | 默认 | 类型 | 字段说明
|
||||
--------- | ------- | ------- | -------- | ----------
|
||||
|owner |是| |string |用户登录名 |
|
||||
|repo |是| |string |项目标识identifier |
|
||||
|
||||
### 返回字段说明
|
||||
参数 | 类型 | 字段说明
|
||||
--------- | ----------- | -----------
|
||||
|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 |迁移创建者头像 |
|
||||
|owner.id |int |迁移接受者的id |
|
||||
|owner.type |string |迁移接受者的类型 |
|
||||
|owner.name |string |迁移接受者的名称 |
|
||||
|owner.login |string |迁移接受者的标识 |
|
||||
|owner.image_url |string |迁移接受者头像 |
|
||||
> 返回的JSON示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"project": {
|
||||
"id": 86,
|
||||
"identifier": "ceshi_repo1",
|
||||
"name": "测试项目啊1",
|
||||
"description": "二十多",
|
||||
"is_public": true,
|
||||
"owner": {
|
||||
"id": 52,
|
||||
"type": "Organization",
|
||||
"name": "身份卡手动阀",
|
||||
"login": "ceshi1",
|
||||
"image_url": "images/avatars/Organization/52?t=1618805056"
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"id": 6,
|
||||
"type": "User",
|
||||
"name": "yystopf",
|
||||
"login": "yystopf",
|
||||
"image_url": "system/lets/letter_avatars/2/Y/241_125_89/120.png"
|
||||
},
|
||||
"owner": {
|
||||
"id": 9,
|
||||
"type": "Organization",
|
||||
"name": "测试组织",
|
||||
"login": "ceshi_org",
|
||||
"image_url": "images/avatars/Organization/9?t=1612706073"
|
||||
},
|
||||
"id": 4,
|
||||
"status": "common",
|
||||
"created_at": "2021-04-26 09:54",
|
||||
"time_ago": "1分钟前"
|
||||
}
|
||||
```
|
||||
|
|
@ -1240,11 +1240,11 @@ await octokit.request('GET /api/yystopf/ceshi/webhooks/3/edit.json')
|
|||
|delete|分支或标签删除|
|
||||
|fork|仓库被fork|
|
||||
|push|git仓库推送|
|
||||
|issue|易修已打开、已关闭、已重新打开或编辑|
|
||||
|issue_assign|易修被指派|
|
||||
|issue_label|易修标签被更新或删除|
|
||||
|issue_milestone|易修被收入里程碑|
|
||||
|issue_comment|易修评论|
|
||||
|issue|疑修已打开、已关闭、已重新打开或编辑|
|
||||
|issue_assign|疑修被指派|
|
||||
|issue_label|疑修标签被更新或删除|
|
||||
|issue_milestone|疑修被收入里程碑|
|
||||
|issue_comment|疑修评论|
|
||||
|pull_request|合并请求|
|
||||
|pull_request_assign|合并请求被指派|
|
||||
|pull_request_label|合并请求被贴上标签|
|
||||
|
|
@ -1337,11 +1337,11 @@ await octokit.request('POST /api/yystopf/ceshi/webhooks.json')
|
|||
|delete|分支或标签删除|
|
||||
|fork|仓库被fork|
|
||||
|push|git仓库推送|
|
||||
|issue|易修已打开、已关闭、已重新打开或编辑|
|
||||
|issue_assign|易修被指派|
|
||||
|issue_label|易修标签被更新或删除|
|
||||
|issue_milestone|易修被收入里程碑|
|
||||
|issue_comment|易修评论|
|
||||
|issue|疑修已打开、已关闭、已重新打开或编辑|
|
||||
|issue_assign|疑修被指派|
|
||||
|issue_label|疑修标签被更新或删除|
|
||||
|issue_milestone|疑修被收入里程碑|
|
||||
|issue_comment|疑修评论|
|
||||
|pull_request|合并请求|
|
||||
|pull_request_assign|合并请求被指派|
|
||||
|pull_request_label|合并请求被贴上标签|
|
||||
|
|
@ -1440,11 +1440,11 @@ await octokit.request('PATCH /api/yystopf/ceshi/webhooks/7.json')
|
|||
|delete|分支或标签删除|
|
||||
|fork|仓库被fork|
|
||||
|push|git仓库推送|
|
||||
|issue|易修已打开、已关闭、已重新打开或编辑|
|
||||
|issue_assign|易修被指派|
|
||||
|issue_label|易修标签被更新或删除|
|
||||
|issue_milestone|易修被收入里程碑|
|
||||
|issue_comment|易修评论|
|
||||
|issue|疑修已打开、已关闭、已重新打开或编辑|
|
||||
|issue_assign|疑修被指派|
|
||||
|issue_label|疑修标签被更新或删除|
|
||||
|issue_milestone|疑修被收入里程碑|
|
||||
|issue_comment|疑修评论|
|
||||
|pull_request|合并请求|
|
||||
|pull_request_assign|合并请求被指派|
|
||||
|pull_request_label|合并请求被贴上标签|
|
||||
|
|
|
|||
|
|
@ -90,13 +90,13 @@ await octokit.request('GET /api/users/:login/messages.json')
|
|||
#### 消息来源source字段说明
|
||||
类型|说明
|
||||
--------- | -----------
|
||||
|IssueAssigned | 有新指派给我的易修 |
|
||||
|IssueAssignerExpire | 我负责的易修截止日期到达最后一天 |
|
||||
|IssueAtme | 在易修中@我 |
|
||||
|IssueChanged | 我创建或负责的易修状态变更 |
|
||||
|IssueCreatorExpire | 我创建的易修截止日期到达最后一天 |
|
||||
|IssueDeleted | 我创建或负责的易修删除 |
|
||||
|IssueJournal | 我创建或负责的易修有新的评论 |
|
||||
|IssueAssigned | 有新指派给我的疑修 |
|
||||
|IssueAssignerExpire | 我负责的疑修截止日期到达最后一天 |
|
||||
|IssueAtme | 在疑修中@我 |
|
||||
|IssueChanged | 我创建或负责的疑修状态变更 |
|
||||
|IssueCreatorExpire | 我创建的疑修截止日期到达最后一天 |
|
||||
|IssueDeleted | 我创建或负责的疑修删除 |
|
||||
|IssueJournal | 我创建或负责的疑修有新的评论 |
|
||||
|LoginIpTip | 登录异常提示 |
|
||||
|OrganizationJoined | 账号被拉入组织 |
|
||||
|OrganizationLeft | 账号被移出组织 |
|
||||
|
|
@ -104,7 +104,7 @@ await octokit.request('GET /api/users/:login/messages.json')
|
|||
|ProjectDeleted | 我关注的仓库被删除 |
|
||||
|ProjectFollowed | 我管理的仓库被关注 |
|
||||
|ProjectForked | 我管理的仓库被复刻 |
|
||||
|ProjectIssue | 我管理/关注的仓库有新的易修 |
|
||||
|ProjectIssue | 我管理/关注的仓库有新的疑修 |
|
||||
|ProjectJoined | 账号被拉入项目 |
|
||||
|ProjectLeft | 账号被移出项目 |
|
||||
|ProjectMemberJoined | 我管理的仓库有成员加入 |
|
||||
|
|
@ -250,7 +250,7 @@ await octokit.request('POST /api/users/:login/messages.json')
|
|||
--------- | ----------- | -----------
|
||||
|type | string | 消息类型 |
|
||||
|receivers_login | array | 需要发送消息的用户名数组|
|
||||
|atmeable_type | string | atme消息对象,是从哪里@我的,比如评论:Journal、易修:Issue、合并请求:PullRequest |
|
||||
|atmeable_type | string | atme消息对象,是从哪里@我的,比如评论:Journal、疑修:Issue、合并请求:PullRequest |
|
||||
|atmeable_id | integer | atme消息对象id |
|
||||
|
||||
> 请求的JSON示例:
|
||||
|
|
@ -469,7 +469,7 @@ await octokit.request('GET /api/template_message_settings.json')
|
|||
"total_settings_count": 4,
|
||||
"settings": [
|
||||
{
|
||||
"name": "易修被指派",
|
||||
"name": "疑修被指派",
|
||||
"key": "IssueAssigned",
|
||||
"notification_disabled": true,
|
||||
"email_disabled": false
|
||||
|
|
@ -488,7 +488,7 @@ await octokit.request('GET /api/template_message_settings.json')
|
|||
"total_settings_count": 4,
|
||||
"settings": [
|
||||
{
|
||||
"name": "有新的易修",
|
||||
"name": "有新的疑修",
|
||||
"key": "Issue",
|
||||
"notification_disabled": true,
|
||||
"email_disabled": false
|
||||
|
|
@ -875,7 +875,7 @@ await octokit.request('GET /api/users/:login/statistics/activity.json')
|
|||
参数 | 类型 | 字段说明
|
||||
--------- | ----------- | -----------
|
||||
|dates |array |时间 |
|
||||
|issues_count |array |易修数量|
|
||||
|issues_count |array |疑修数量|
|
||||
|pull_requests_count |array |合并请求数量|
|
||||
|commtis_count |array |贡献数量|
|
||||
|
||||
|
|
@ -1084,7 +1084,7 @@ await octokit.request('GET /api/users/:login/project_trends.json')
|
|||
参数 | 类型 | 字段说明
|
||||
--------- | ----------- | -----------
|
||||
|total_count |int |所选时间内的总动态数 |
|
||||
|project_trends.trend_type |string|动态类型,Issue:易修,VersionRelease:版本发布,PullRequest:合并请求|
|
||||
|project_trends.trend_type |string|动态类型,Issue:疑修,VersionRelease:版本发布,PullRequest:合并请求|
|
||||
|project_trends.action_type |string|操作类型|
|
||||
|project_trends.trend_id |integer|动态id|
|
||||
|project_trends.user_name |string|用户名称|
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
class Organizations::CreateForm < BaseForm
|
||||
NAME_REGEX = /^(?!_)(?!.*?_$)[a-zA-Z0-9_-]+$/ #只含有数字、字母、下划线不能以下划线开头和结尾
|
||||
attr_accessor :name, :description, :website, :location, :repo_admin_change_team_access, :visibility, :max_repo_creation, :nickname
|
||||
attr_accessor :name, :description, :website, :location, :repo_admin_change_team_access, :visibility, :max_repo_creation, :nickname, :original_name
|
||||
|
||||
validates :name, :nickname, :visibility, presence: true
|
||||
validates :name, :nickname, length: { maximum: 100 }
|
||||
|
|
@ -9,7 +9,7 @@ class Organizations::CreateForm < BaseForm
|
|||
validates :name, format: { with: NAME_REGEX, multiline: true, message: "只能含有数字、字母、下划线且不能以下划线开头和结尾" }
|
||||
|
||||
validate do
|
||||
check_name(name) unless name.blank?
|
||||
check_name(name) unless name.blank? || name == original_name
|
||||
end
|
||||
|
||||
def check_name(name)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
module Register
|
||||
class RemoteForm < Register::BaseForm
|
||||
# login 登陆方式,支持邮箱、登陆、手机号等
|
||||
attr_accessor :username, :email, :password, :platform
|
||||
|
||||
validates :username, :email, :password, presence: true
|
||||
validate :check!
|
||||
|
||||
def check!
|
||||
Rails.logger.info "Register::RemoteForm params: username: #{username}; email: #{email}; password: #{password}; platform: #{platform}"
|
||||
check_login(username)
|
||||
check_mail(email)
|
||||
check_password(password)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -4,5 +4,5 @@ class Users::LoginForm
|
|||
attr_accessor :password, :login
|
||||
|
||||
validates :login, presence: true
|
||||
validates :password, presence: true, length: { minimum: 8, maximum: 16 }, format: { with: CustomRegexp::PASSWORD, message: "8~16位,支持字母数字和符号" }
|
||||
validates :password, presence: true, length: { minimum: 6, maximum: 16 }, format: { with: CustomRegexp::LOGIN_PASSWORD, message: "6~16位,支持字母数字和符号" }
|
||||
end
|
||||
|
|
@ -45,7 +45,7 @@ module RepositoriesHelper
|
|||
end
|
||||
end
|
||||
|
||||
def readme_render_decode64_content(str, path)
|
||||
def readme_render_decode64_content(str, owner, repo, ref)
|
||||
return nil if str.blank?
|
||||
begin
|
||||
content = Base64.decode64(str).force_encoding('UTF-8')
|
||||
|
|
@ -63,13 +63,16 @@ module RepositoriesHelper
|
|||
if remove_title.length > 0
|
||||
r_content = r_content.gsub(/#{remove_title[0]}/, "").strip
|
||||
end
|
||||
if r_content.include?("?")
|
||||
new_r_content = r_content + "&raw=true"
|
||||
else
|
||||
new_r_content = r_content + "?raw=true"
|
||||
end
|
||||
# if r_content.include?("?")
|
||||
# new_r_content = r_content + "&raw=true"
|
||||
# else
|
||||
# new_r_content = r_content + "?raw=true"
|
||||
# end
|
||||
new_r_content = r_content
|
||||
|
||||
unless r_content.include?("http://") || r_content.include?("https://") || r_content.include?("mailto:")
|
||||
new_r_content = "#{path}" + new_r_content
|
||||
# new_r_content = "#{path}" + new_r_content
|
||||
new_r_content = [base_url, "/api/#{owner&.login}/#{repo.identifier}/raw?filepath=#{r_content}&ref=#{ref}"].join
|
||||
end
|
||||
content = content.gsub(/#{r_content}/, new_r_content)
|
||||
end
|
||||
|
|
@ -94,7 +97,7 @@ module RepositoriesHelper
|
|||
def decode64_content(entry, owner, repo, ref, path=nil)
|
||||
if is_readme?(entry['type'], entry['name'])
|
||||
content = Gitea::Repository::Entries::GetService.call(owner, repo.identifier, URI.escape(entry['path']), ref: ref)['content']
|
||||
readme_render_decode64_content(content, path)
|
||||
readme_render_decode64_content(content, owner, repo, ref)
|
||||
else
|
||||
file_type = File.extname(entry['name'].to_s)[1..-1]
|
||||
if image_type?(file_type)
|
||||
|
|
|
|||
|
|
@ -26,8 +26,12 @@ module TagChosenHelper
|
|||
end
|
||||
|
||||
def render_branches(project)
|
||||
branches = Gitea::Repository::Branches::ListService.call(project&.owner, project.identifier)
|
||||
branches.collect{|i| i["name"] if i.is_a?(Hash)}
|
||||
if project.educoder?
|
||||
return ['master']
|
||||
else
|
||||
branches = Gitea::Repository::Branches::ListService.call(project&.owner, project.identifier)
|
||||
branches.collect{|i| i["name"] if i.is_a?(Hash)}
|
||||
end
|
||||
end
|
||||
|
||||
def render_cache_trackers
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ class SendTemplateMessageJob < ApplicationJob
|
|||
issue = Issue.find_by_id(issue_id)
|
||||
return unless operator.present? && issue.present?
|
||||
# receivers = receivers.where.not(id: operator&.id)
|
||||
receivers = User.where(id: receivers)
|
||||
receivers_string, content, notification_url = MessageTemplate::IssueAtme.get_message_content(receivers, operator, issue)
|
||||
Notice::Write::CreateService.call(receivers_string, content, notification_url, source, {operator_id: operator.id, issue_id: issue.id}, 2, operator_id)
|
||||
when 'IssueChanged'
|
||||
|
|
@ -93,18 +94,6 @@ class SendTemplateMessageJob < ApplicationJob
|
|||
receivers_email_string, email_title, email_content = MessageTemplate::OrganizationLeft.get_email_message_content(receiver, organization)
|
||||
Notice::Write::EmailCreateService.call(receivers_email_string, email_title, email_content)
|
||||
end
|
||||
when 'OrganizationRole'
|
||||
user_id, organization_id, role = args[0], args[1], args[2]
|
||||
user = User.find_by_id(user_id)
|
||||
organization = Organization.find_by_id(organization_id)
|
||||
return unless user.present? && organization.present?
|
||||
receivers = User.where(id: user.id)
|
||||
receivers_string, content, notification_url = MessageTemplate::OrganizationRole.get_message_content(receivers, organization, role)
|
||||
Notice::Write::CreateService.call(receivers_string, content, notification_url, source, {user_id: user.id, organization_id: organization.id, role: role})
|
||||
receivers.find_each do |receiver|
|
||||
receivers_email_string, email_title, email_content = MessageTemplate::OrganizationRole.get_email_message_content(receiver, organization, role)
|
||||
Notice::Write::EmailCreateService.call(receivers_email_string, email_title, email_content)
|
||||
end
|
||||
when 'ProjectIssue'
|
||||
operator_id, issue_id = args[0], args[1]
|
||||
operator = User.find_by_id(operator_id)
|
||||
|
|
@ -235,6 +224,7 @@ class SendTemplateMessageJob < ApplicationJob
|
|||
pull_request = PullRequest.find_by_id(pull_request_id)
|
||||
return unless operator.present? && pull_request.present?
|
||||
# receivers = receivers.where.not(id: operator&.id)
|
||||
receivers = User.where(id: receivers)
|
||||
receivers_string, content, notification_url = MessageTemplate::PullRequestAtme.get_message_content(receivers, operator, pull_request)
|
||||
Notice::Write::CreateService.call(receivers_string, content, notification_url, source, {operator_id: operator.id, pull_request_id: pull_request.id}, 2, operator_id)
|
||||
when 'PullRequestChanged'
|
||||
|
|
@ -274,6 +264,32 @@ class SendTemplateMessageJob < ApplicationJob
|
|||
receivers_email_string, email_title, email_content = MessageTemplate::PullRequestMerged.get_email_message_content(receiver, operator, pull_request)
|
||||
Notice::Write::EmailCreateService.call(receivers_email_string, email_title, email_content)
|
||||
end
|
||||
when 'TeamJoined'
|
||||
user_id, organization_id, team_id = args[0], args[1], args[2]
|
||||
user = User.find_by_id(user_id)
|
||||
organization = Organization.find_by_id(organization_id)
|
||||
team = Team.find_by_id(team_id)
|
||||
return unless user.present? && organization.present? && team.present?
|
||||
receivers = User.where(id: user.id)
|
||||
receivers_string, content, notification_url = MessageTemplate::TeamJoined.get_message_content(receivers, organization, team)
|
||||
Notice::Write::CreateService.call(receivers_string, content, notification_url, source, {user_id: user.id, organization_id: organization.id, team_id: team.id})
|
||||
receivers.find_each do |receiver|
|
||||
receivers_email_string, email_title, email_content = MessageTemplate::TeamJoined.get_email_message_content(receiver, organization, team)
|
||||
Notice::Write::EmailCreateService.call(receivers_email_string, email_title, email_content)
|
||||
end
|
||||
when 'TeamLeft'
|
||||
user_id, organization_id, team_id = args[0], args[1], args[2]
|
||||
user = User.find_by_id(user_id)
|
||||
organization = Organization.find_by_id(organization_id)
|
||||
team = Team.find_by_id(team_id)
|
||||
return unless user.present? && organization.present? && team.present?
|
||||
receivers = User.where(id: user.id)
|
||||
receivers_string, content, notification_url = MessageTemplate::TeamLeft.get_message_content(receivers, organization, team)
|
||||
Notice::Write::CreateService.call(receivers_string, content, notification_url, source, {user_id: user.id, organization_id: organization.id, team_id: team.id})
|
||||
receivers.find_each do |receiver|
|
||||
receivers_email_string, email_title, email_content = MessageTemplate::TeamLeft.get_email_message_content(receiver, organization, team)
|
||||
Notice::Write::EmailCreateService.call(receivers_email_string, email_title, email_content)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -5,6 +5,7 @@ module CustomRegexp
|
|||
LASTNAME = /\A[a-zA-Z0-9\u4e00-\u9fa5]+\z/
|
||||
NICKNAME = /\A[\u4e00-\u9fa5_a-zA-Z0-9]+\z/
|
||||
PASSWORD = /\A[a-z_A-Z0-9\-\.!@#\$%\\\^&\*\)\(\+=\{\}\[\]\/",'_<>~\·`\?:;|]{8,16}\z/
|
||||
LOGIN_PASSWORD = /\A[a-z_A-Z0-9\-\.!@#\$%\\\^&\*\)\(\+=\{\}\[\]\/",'_<>~\·`\?:;|]{6,16}\z/
|
||||
URL = /\Ahttps?:\/\/[-A-Za-z0-9+&@#\/%?=~_|!:,.;]+[-A-Za-z0-9+&@#\/%=~_|]\z/
|
||||
IP = /^((\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])\.){3}(\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])$/
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: claims
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# issue_id :integer
|
||||
# user_id :integer
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# note :text(65535)
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_claims_on_issue_id (issue_id)
|
||||
# index_claims_on_user_id (user_id)
|
||||
#
|
||||
|
||||
class Claim < ApplicationRecord
|
||||
belongs_to :user, foreign_key: :user_id
|
||||
scope :claim_includes, ->{includes(:user)}
|
||||
end
|
||||
|
|
@ -21,13 +21,37 @@ module ProjectOperable
|
|||
end
|
||||
|
||||
def add_member!(user_id, role_name='Developer')
|
||||
member = members.create!(user_id: user_id)
|
||||
if self.owner.is_a?(Organization)
|
||||
case role_name
|
||||
when 'Manager'
|
||||
team = self.owner.teams.admin.take
|
||||
team = team.nil? ? Team.build(self.user_id, 'admin', '管理员', '', 'admin', false, false) : team
|
||||
TeamProject.build(self.user_id, team.id, self.id)
|
||||
OrganizationUser.build(self.user_id, user_id)
|
||||
team_user = TeamUser.build(self.user_id, user_id, team.id)
|
||||
when 'Developer'
|
||||
team = self.owner.teams.write.take
|
||||
team = team.nil? ? Team.build(self.user_id, 'developer', '开发者', '', 'write', false, false) : team
|
||||
TeamProject.build(self.user_id, team.id, self.id)
|
||||
OrganizationUser.build(self.user_id, user_id)
|
||||
team_user = TeamUser.build(self.user_id, user_id, team.id)
|
||||
when 'Reporter'
|
||||
team = self.owner.teams.read.take
|
||||
team = team.nil? ? Team.build(self.user_id, 'reporter', '报告者', '', 'read', false, false) : team
|
||||
TeamProject.build(self.user_id, team.id, self.id)
|
||||
OrganizationUser.build(self.user_id, user_id)
|
||||
team_user = TeamUser.build(self.user_id, user_id, team.id)
|
||||
end
|
||||
end
|
||||
member = members.create!(user_id: user_id, team_user_id: team_user&.id)
|
||||
set_developer_role(member, role_name)
|
||||
end
|
||||
|
||||
def remove_member!(user_id)
|
||||
member = members.find_by(user_id: user_id)
|
||||
member.destroy! if member && self.user_id != user_id
|
||||
team_user = TeamUser.find_by_id(member&.team_user_id)
|
||||
team_user.destroy! if team_user
|
||||
end
|
||||
|
||||
def member?(user_id)
|
||||
|
|
@ -47,6 +71,28 @@ module ProjectOperable
|
|||
|
||||
def change_member_role!(user_id, role)
|
||||
member = self.member(user_id)
|
||||
if self.owner.is_a?(Organization) && member.team_user.present?
|
||||
case role&.name
|
||||
when 'Manager'
|
||||
team = self.owner.teams.admin.take
|
||||
team = team.nil? ? Team.build(self.user_id, 'admin', '管理员', '', 'admin', false, false) : team
|
||||
TeamProject.build(self.user_id, team.id, self.id)
|
||||
OrganizationUser.build(self.user_id, user_id)
|
||||
team_user = member.team_user.update(team_id: team&.id)
|
||||
when 'Developer'
|
||||
team = self.owner.teams.write.take
|
||||
team = team.nil? ? Team.build(self.user_id, 'developer', '开发者', '', 'write', false, false) : team
|
||||
TeamProject.build(self.user_id, team.id, self.id)
|
||||
OrganizationUser.build(self.user_id, user_id)
|
||||
team_user = member.team_user.update(team_id: team&.id)
|
||||
when 'Reporter'
|
||||
team = self.owner.teams.read.take
|
||||
team = team.nil? ? Team.build(self.user_id, 'reporter', '报告者', '', 'read', false, false) : team
|
||||
TeamProject.build(self.user_id, team.id, self.id)
|
||||
OrganizationUser.build(self.user_id, user_id)
|
||||
team_user = member.team_user.update(team_id: team&.id)
|
||||
end
|
||||
end
|
||||
member.member_roles.last.update_attributes!(role: role)
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ class Issue < ApplicationRecord
|
|||
# has_many :memos
|
||||
has_many :journals, :as => :journalized, :dependent => :destroy
|
||||
has_many :journal_details, through: :journals
|
||||
has_many :claims, :dependent => :destroy
|
||||
has_many :issue_tags_relates, dependent: :destroy
|
||||
has_many :issue_tags, through: :issue_tags_relates
|
||||
has_many :issue_times, dependent: :destroy
|
||||
|
|
@ -154,7 +155,7 @@ class Issue < ApplicationRecord
|
|||
end
|
||||
|
||||
def is_collaborators?
|
||||
self.assigned_to_id.present? ? self.project.members.where(user_id: self.assigned_to_id).present? : false
|
||||
self.assigned_to_id.present? ? self.project.member?(self.assigned_to_id) : false
|
||||
end
|
||||
|
||||
def get_issue_tags_name
|
||||
|
|
|
|||
|
|
@ -11,23 +11,26 @@
|
|||
# course_group_id :integer default("0")
|
||||
# is_collect :integer default("1")
|
||||
# graduation_group_id :integer default("0")
|
||||
# team_user_id :integer
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_members_on_course_id (course_id)
|
||||
# index_members_on_project_id (project_id)
|
||||
# index_members_on_team_user_id (team_user_id)
|
||||
# index_members_on_user_id (user_id)
|
||||
# index_members_on_user_id_and_project_id (user_id,project_id,course_id) UNIQUE
|
||||
#
|
||||
|
||||
class Member < ApplicationRecord
|
||||
belongs_to :user
|
||||
# belongs_to :course, optional: true
|
||||
belongs_to :project, optional: true
|
||||
|
||||
has_many :member_roles, dependent: :destroy
|
||||
has_many :roles, through: :member_roles
|
||||
|
||||
validates :user_id, :project_id, presence: true
|
||||
|
||||
end
|
||||
class Member < ApplicationRecord
|
||||
belongs_to :user
|
||||
# belongs_to :course, optional: true
|
||||
belongs_to :project, optional: true
|
||||
belongs_to :team_user, optional: true
|
||||
|
||||
has_many :member_roles, dependent: :destroy
|
||||
has_many :roles, through: :member_roles
|
||||
|
||||
validates :user_id, :project_id, presence: true
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -17,27 +17,25 @@ class MessageTemplate < ApplicationRecord
|
|||
def self.build_init_data
|
||||
self.create(type: 'MessageTemplate::FollowedTip', sys_notice: '<b>{nickname}</b> 关注了你', notification_url: '{baseurl}/{login}')
|
||||
email_html = File.read("#{email_template_html_dir}/issue_assigned.html")
|
||||
self.create(type: 'MessageTemplate::IssueAssigned', sys_notice: '{nickname1}在 <b>{nickname2}/{repository}</b> 指派给你一个易修:<b>{title}</b>', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}', email: email_html, email_title: 'GitLink: {nickname1} 在 {nickname2}/{repository} 指派给你一个易修')
|
||||
self.create(type: 'MessageTemplate::IssueAssignerExpire', sys_notice: '您负责的易修 <b>{title}</b> 已临近截止日期,请尽快处理', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}')
|
||||
self.create(type: 'MessageTemplate::IssueAtme', sys_notice: '<b>{nickname}</b> 在易修 <b>{title}</b> 中@我', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}')
|
||||
self.create(type: 'MessageTemplate::IssueAssigned', sys_notice: '{nickname1}在 <b>{nickname2}/{repository}</b> 指派给你一个疑修:<b>{title}</b>', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}', email: email_html, email_title: 'GitLink: {nickname1} 在 {nickname2}/{repository} 指派给你一个疑修')
|
||||
self.create(type: 'MessageTemplate::IssueAssignerExpire', sys_notice: '您负责的疑修 <b>{title}</b> 已临近截止日期,请尽快处理', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}')
|
||||
self.create(type: 'MessageTemplate::IssueAtme', sys_notice: '<b>{nickname}</b> 在疑修 <b>{title}</b> 中@我', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}')
|
||||
email_html = File.read("#{email_template_html_dir}/issue_changed.html")
|
||||
self.create(type: 'MessageTemplate::IssueChanged', sys_notice: '在项目 <b>{nickname2}/{repository}</b> 的易修 <b>{title}</b> 中:{ifassigner}{nickname1}将负责人从 <b>{assigner1}</b> 修改为 <b>{assigner2}</b> {endassigner}{ifstatus}{nickname1}将状态从 <b>{status1}</b> 修改为 <b>{status2}</b> {endstatus}{iftracker}{nickname1}将类型从 <b>{tracker1}</b> 修改为 <b>{tracker2}</b> {endtracker}{ifpriority}{nickname1}将优先级从 <b>{priority1}</b> 修改为 <b>{priority2}</b> {endpriority}{ifmilestone}{nickname1}将里程碑从 <b>{milestone1}</b> 修改为 <b>{milestone2}</b> {endmilestone}{iftag}{nickname1}将标记从 <b>{tag1}</b> 修改为 <b>{tag2}</b> {endtag}{ifdoneratio}{nickname1}将完成度从 <b>{doneratio1}</b> 修改为 <b>{doneratio2}</b> {enddoneratio}{ifbranch}{nickname1}将指定分支从 <b>{branch1}</b> 修改为 <b>{branch2}</b> {endbranch}{ifstartdate}{nickname1}将开始日期从 <b>{startdate1}</b> 修改为 <b>{startdate2}</b> {endstartdate}{ifduedate}{nickname1}将结束日期从 <b>{duedate1}</b> 修改为 <b>{duedate2}</b> {endduedate}', email: email_html, email_title: 'GitLink: 易修 {title} 有状态变更', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}')
|
||||
self.create(type: 'MessageTemplate::IssueCreatorExpire', sys_notice: '您发布的易修 <b>{title}</b> 已临近截止日期,请尽快处理', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}')
|
||||
self.create(type: 'MessageTemplate::IssueChanged', sys_notice: '在项目 <b>{nickname2}/{repository}</b> 的疑修 <b>{title}</b> 中:{ifassigner}{nickname1}将负责人从 <b>{assigner1}</b> 修改为 <b>{assigner2}</b> {endassigner}{ifstatus}{nickname1}将状态从 <b>{status1}</b> 修改为 <b>{status2}</b> {endstatus}{iftracker}{nickname1}将类型从 <b>{tracker1}</b> 修改为 <b>{tracker2}</b> {endtracker}{ifpriority}{nickname1}将优先级从 <b>{priority1}</b> 修改为 <b>{priority2}</b> {endpriority}{ifmilestone}{nickname1}将里程碑从 <b>{milestone1}</b> 修改为 <b>{milestone2}</b> {endmilestone}{iftag}{nickname1}将标记从 <b>{tag1}</b> 修改为 <b>{tag2}</b> {endtag}{ifdoneratio}{nickname1}将完成度从 <b>{doneratio1}</b> 修改为 <b>{doneratio2}</b> {enddoneratio}{ifbranch}{nickname1}将指定分支从 <b>{branch1}</b> 修改为 <b>{branch2}</b> {endbranch}{ifstartdate}{nickname1}将开始日期从 <b>{startdate1}</b> 修改为 <b>{startdate2}</b> {endstartdate}{ifduedate}{nickname1}将结束日期从 <b>{duedate1}</b> 修改为 <b>{duedate2}</b> {endduedate}', email: email_html, email_title: 'GitLink: 疑修 {title} 有状态变更', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}')
|
||||
self.create(type: 'MessageTemplate::IssueCreatorExpire', sys_notice: '您发布的疑修 <b>{title}</b> 已临近截止日期,请尽快处理', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}')
|
||||
email_html = File.read("#{email_template_html_dir}/issue_deleted.html")
|
||||
self.create(type: 'MessageTemplate::IssueDeleted', sys_notice: '{nickname}已将易修 <b>{title}</b> 删除', email: email_html, email_title: 'GitLink: 易修 {title} 有状态变更', notification_url: '')
|
||||
self.create(type: 'MessageTemplate::IssueJournal', sys_notice: '{nickname}评论易修{title}:<b>{notes}</b>', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}')
|
||||
self.create(type: 'MessageTemplate::IssueDeleted', sys_notice: '{nickname}已将疑修 <b>{title}</b> 删除', email: email_html, email_title: 'GitLink: 疑修 {title} 有状态变更', notification_url: '')
|
||||
self.create(type: 'MessageTemplate::IssueJournal', sys_notice: '{nickname}评论疑修{title}:<b>{notes}</b>', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}')
|
||||
self.create(type: 'MessageTemplate::LoginIpTip', sys_notice: '您的账号{nickname}于{login_time)在非常用的IP地址{ip}登录,如非本人操作,请立即修改密码', notification_url: '')
|
||||
email_html = File.read("#{email_template_html_dir}/organization_joined.html")
|
||||
self.create(type: 'MessageTemplate::OrganizationJoined', sys_notice: '你已加入 <b>{organization}</b> 组织', notification_url: '{baseurl}/{login}', email: email_html, email_title: 'GitLink: 你已加入 {organization} 组织')
|
||||
email_html = File.read("#{email_template_html_dir}/organization_left.html")
|
||||
self.create(type: 'MessageTemplate::OrganizationLeft', sys_notice: '你已被移出 <b>{organization}</b> 组织', notification_url: '', email: email_html, email_title: 'GitLink: 你已被移出 {organization} 组织')
|
||||
email_html = File.read("#{email_template_html_dir}/organization_role.html")
|
||||
self.create(type: 'MessageTemplate::OrganizationRole', sys_notice: '组织 <b>{organization}</b> 已把你的角色改为 <b>{role}</b>', email: email_html, email_title: 'GitLink: 在 {organization} 组织你的账号有权限变更', notification_url: '{baseurl}/{login}')
|
||||
self.create(type: 'MessageTemplate::ProjectDeleted', sys_notice: '你关注的仓库{nickname}/{repository}已被删除', notification_url: '')
|
||||
self.create(type: 'MessageTemplate::ProjectFollowed', sys_notice: '<b>{nickname}</b> 关注了你管理的仓库', notification_url: '{baseurl}/{login}')
|
||||
self.create(type: 'MessageTemplate::ProjectForked', sys_notice: '<b>{nickname1}</b> 复刻了你管理的仓库{nickname1}/{repository1}到{nickname2}/{repository2}', notification_url: '{baseurl}/{owner}/{identifier}')
|
||||
email_html = File.read("#{email_template_html_dir}/project_issue.html")
|
||||
self.create(type: 'MessageTemplate::ProjectIssue', sys_notice: '{nickname1}在 <b>{nickname2}/{repository}</b> 新建易修:<b>{title}</b>', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}', email: email_html, email_title: 'GitLink: {nickname1} 在 {nickname2}/{repository} 新建了一个易修')
|
||||
self.create(type: 'MessageTemplate::ProjectIssue', sys_notice: '{nickname1}在 <b>{nickname2}/{repository}</b> 新建疑修:<b>{title}</b>', notification_url: '{baseurl}/{owner}/{identifier}/issues/{id}', email: email_html, email_title: 'GitLink: {nickname1} 在 {nickname2}/{repository} 新建了一个疑修')
|
||||
email_html = File.read("#{email_template_html_dir}/project_joined.html")
|
||||
self.create(type: 'MessageTemplate::ProjectJoined', sys_notice: '你已加入 <b>{repository}</b> 项目', notification_url: '{baseurl}/{owner}/{identifier}', email: email_html, email_title: 'GitLink: 你已加入 {repository} 项目')
|
||||
email_html = File.read("#{email_template_html_dir}/project_left.html")
|
||||
|
|
@ -66,6 +64,10 @@ class MessageTemplate < ApplicationRecord
|
|||
self.create(type: 'MessageTemplate::PullRequestJournal', sys_notice: '{nickname}评论合并请求{title}:<b>{notes}</b>', notification_url: '{baseurl}/{owner}/{identifier}/pulls/{id}')
|
||||
email_html = File.read("#{email_template_html_dir}/pull_request_merged.html")
|
||||
self.create(type: 'MessageTemplate::PullRequestMerged', sys_notice: '你提交的合并请求:{title} <b>已通过</b>', email: email_html, email_title: 'GitLink: 合并请求 {title} 有状态变更', notification_url: '{baseurl}/{owner}/{identifier}/pulls/{id}')
|
||||
email_html = File.read("#{email_template_html_dir}/team_joined.html")
|
||||
self.create(type: 'MessageTemplate::TeamJoined', sys_notice: '你已被拉入组织 <b>{organization}</b> 的 <b>{team}</b> 团队,拥有<b>{role}</b>权限', email: email_html, email_title: 'GitLink: 在 {organization} 组织你的账号有权限变更', notification_url: '{baseurl}/{login}')
|
||||
email_html = File.read("#{email_template_html_dir}/team_left.html")
|
||||
self.create(type: 'MessageTemplate::TeamLeft', sys_notice: '你已被移出组织 <b>{organization}</b> 的 <b>{team}</b> 团队', email: email_html, email_title: 'GitLink: 在 {organization} 组织你的账号有权限变更', notification_url: '{baseurl}/{login}')
|
||||
end
|
||||
|
||||
def self.sys_notice
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
# email_title :string(255)
|
||||
#
|
||||
|
||||
# 有新指派给我的易修
|
||||
# 有新指派给我的疑修
|
||||
class MessageTemplate::IssueAssigned < MessageTemplate
|
||||
|
||||
# MessageTemplate::IssueAssigned.get_message_content(User.where(login: 'yystopf'), User.last, Issue.last)
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
# email_title :string(255)
|
||||
#
|
||||
|
||||
# 我负责的易修截止日期到达最后一天
|
||||
# 我负责的疑修截止日期到达最后一天
|
||||
class MessageTemplate::IssueAssignerExpire < MessageTemplate
|
||||
|
||||
# MessageTemplate::IssueAssignerExpire.get_message_content(User.where(login: 'yystopf'), Issue.last)
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
# email_title :string(255)
|
||||
#
|
||||
|
||||
# 在易修中@我
|
||||
# 在疑修中@我
|
||||
class MessageTemplate::IssueAtme < MessageTemplate
|
||||
|
||||
# MessageTemplate::IssueAtme.get_message_content(User.where(login: 'yystopf'), User.last, Issue.last)
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
# email_title :string(255)
|
||||
#
|
||||
|
||||
# 我创建或负责的易修状态变更
|
||||
# 我创建或负责的疑修状态变更
|
||||
class MessageTemplate::IssueChanged < MessageTemplate
|
||||
|
||||
# MessageTemplate::IssueChanged.get_message_content(User.where(login: 'yystopf'), User.last, Issue.last, {status_id: [1, 2], assigned_to_id: [nil, 203], tracker_id: [4, 3], priority_id: [2, 4], fixed_version_id: [nil, 5], due_date: ['', '2021-09-11'], done_ratio: [0, 40], issue_tags_value: ["", "7"], branch_name: ["", "master"]})
|
||||
|
|
@ -29,7 +29,7 @@ class MessageTemplate::IssueChanged < MessageTemplate
|
|||
content = MessageTemplate::IssueChanged.sys_notice.gsub('{nickname1}', operator&.real_name).gsub('{nickname2}', owner&.real_name).gsub('{repository}', project&.name).gsub('{title}', issue&.subject)
|
||||
url = notification_url.gsub('{owner}', owner&.login).gsub('{identifier}', project&.identifier).gsub('{id}', issue&.id.to_s)
|
||||
change_count = change_params.keys.size
|
||||
# 易修负责人修改
|
||||
# 疑修负责人修改
|
||||
if change_params[:assigned_to_id].present?
|
||||
assigner1 = User.find_by_id(change_params[:assigned_to_id][0])
|
||||
assigner2 = User.find_by_id(change_params[:assigned_to_id][1])
|
||||
|
|
@ -44,7 +44,7 @@ class MessageTemplate::IssueChanged < MessageTemplate
|
|||
else
|
||||
content.gsub!(/({ifassigner})(.*)({endassigner})/, '')
|
||||
end
|
||||
# 易修状态修改
|
||||
# 疑修状态修改
|
||||
if change_params[:status_id].present?
|
||||
status1 = IssueStatus.find_by_id(change_params[:status_id][0])
|
||||
status2 = IssueStatus.find_by_id(change_params[:status_id][1])
|
||||
|
|
@ -59,7 +59,7 @@ class MessageTemplate::IssueChanged < MessageTemplate
|
|||
else
|
||||
content.gsub!(/({ifstatus})(.*)({endstatus})/, '')
|
||||
end
|
||||
# 易修类型修改
|
||||
# 疑修类型修改
|
||||
if change_params[:tracker_id].present?
|
||||
tracker1 = Tracker.find_by_id(change_params[:tracker_id][0])
|
||||
tracker2 = Tracker.find_by_id(change_params[:tracker_id][1])
|
||||
|
|
@ -74,7 +74,7 @@ class MessageTemplate::IssueChanged < MessageTemplate
|
|||
else
|
||||
content.gsub!(/({iftracker})(.*)({endtracker})/, '')
|
||||
end
|
||||
# 易修里程碑修改
|
||||
# 疑修里程碑修改
|
||||
if change_params[:fixed_version_id].present?
|
||||
fix_version1 = Version.find_by_id(change_params[:fixed_version_id][0])
|
||||
fix_version2 = Version.find_by_id(change_params[:fixed_version_id][1])
|
||||
|
|
@ -89,7 +89,7 @@ class MessageTemplate::IssueChanged < MessageTemplate
|
|||
else
|
||||
content.gsub!(/({ifmilestone})(.*)({endmilestone})/, '')
|
||||
end
|
||||
# 易修标记修改
|
||||
# 疑修标记修改
|
||||
if change_params[:issue_tags_value].present?
|
||||
issue_tags1 = IssueTag.where(id: change_params[:issue_tags_value][0]).distinct
|
||||
issue_tags2 = IssueTag.where(id: change_params[:issue_tags_value][1]).distinct
|
||||
|
|
@ -106,7 +106,7 @@ class MessageTemplate::IssueChanged < MessageTemplate
|
|||
else
|
||||
content.gsub!(/({iftag})(.*)({endtag})()/, '')
|
||||
end
|
||||
# 易修优先级修改
|
||||
# 疑修优先级修改
|
||||
if change_params[:priority_id].present?
|
||||
priority1 = IssuePriority.find_by_id(change_params[:priority_id][0])
|
||||
priority2 = IssuePriority.find_by_id(change_params[:priority_id][1])
|
||||
|
|
@ -121,7 +121,7 @@ class MessageTemplate::IssueChanged < MessageTemplate
|
|||
else
|
||||
content.gsub!(/({ifpriority})(.*)({endpriority})/, '')
|
||||
end
|
||||
# 易修完成度修改
|
||||
# 疑修完成度修改
|
||||
if change_params[:done_ratio].present?
|
||||
doneratio1 = change_params[:done_ratio][0]
|
||||
doneratio2 = change_params[:done_ratio][1]
|
||||
|
|
@ -136,7 +136,7 @@ class MessageTemplate::IssueChanged < MessageTemplate
|
|||
else
|
||||
content.gsub!(/({ifdoneratio})(.*)({enddoneratio})/, '')
|
||||
end
|
||||
# 易修指定分支修改
|
||||
# 疑修指定分支修改
|
||||
if change_params[:branch_name].present?
|
||||
branch1 = change_params[:branch_name][0].blank? ? '分支未指定' : change_params[:branch_name][0]
|
||||
branch2 = change_params[:branch_name][1].blank? ? '分支未指定' : change_params[:branch_name][1]
|
||||
|
|
@ -151,7 +151,7 @@ class MessageTemplate::IssueChanged < MessageTemplate
|
|||
else
|
||||
content.gsub!(/({ifbranch})(.*)({endbranch})/, '')
|
||||
end
|
||||
# 易修开始日期修改
|
||||
# 疑修开始日期修改
|
||||
if change_params[:start_date].present?
|
||||
startdate1 = change_params[:start_date][0].blank? ? "未选择开始日期" : change_params[:start_date][0]
|
||||
startdate2 = change_params[:start_date][1].blank? ? "未选择开始日期" : change_params[:start_date][1]
|
||||
|
|
@ -166,7 +166,7 @@ class MessageTemplate::IssueChanged < MessageTemplate
|
|||
else
|
||||
content.gsub!(/({ifstartdate})(.*)({endstartdate})/, '')
|
||||
end
|
||||
# 易修结束日期修改
|
||||
# 疑修结束日期修改
|
||||
if change_params[:due_date].present?
|
||||
duedate1 = change_params[:due_date][0].blank? ? '未选择结束日期' : change_params[:due_date][0]
|
||||
duedate2 = change_params[:due_date][1].blank? ? '未选择结束日期' : change_params[:due_date][1]
|
||||
|
|
@ -207,7 +207,7 @@ class MessageTemplate::IssueChanged < MessageTemplate
|
|||
content.gsub!('{title}', issue&.subject)
|
||||
content.gsub!('{id}', issue&.id.to_s)
|
||||
change_count = change_params.keys.size
|
||||
# 易修负责人修改
|
||||
# 疑修负责人修改
|
||||
if change_params[:assigned_to_id].present?
|
||||
assigner1 = User.find_by_id(change_params[:assigned_to_id][0])
|
||||
assigner2 = User.find_by_id(change_params[:assigned_to_id][1])
|
||||
|
|
@ -222,7 +222,7 @@ class MessageTemplate::IssueChanged < MessageTemplate
|
|||
else
|
||||
content.gsub!(/({ifassigner})(.*)({endassigner})/, '')
|
||||
end
|
||||
# 易修状态修改
|
||||
# 疑修状态修改
|
||||
if change_params[:status_id].present?
|
||||
status1 = IssueStatus.find_by_id(change_params[:status_id][0])
|
||||
status2 = IssueStatus.find_by_id(change_params[:status_id][1])
|
||||
|
|
@ -237,7 +237,7 @@ class MessageTemplate::IssueChanged < MessageTemplate
|
|||
else
|
||||
content.gsub!(/({ifstatus})(.*)({endstatus})/, '')
|
||||
end
|
||||
# 易修类型修改
|
||||
# 疑修类型修改
|
||||
if change_params[:tracker_id].present?
|
||||
tracker1 = Tracker.find_by_id(change_params[:tracker_id][0])
|
||||
tracker2 = Tracker.find_by_id(change_params[:tracker_id][1])
|
||||
|
|
@ -252,7 +252,7 @@ class MessageTemplate::IssueChanged < MessageTemplate
|
|||
else
|
||||
content.gsub!(/({iftracker})(.*)({endtracker})/, '')
|
||||
end
|
||||
# 易修里程碑修改
|
||||
# 疑修里程碑修改
|
||||
if change_params[:fixed_version_id].present?
|
||||
fix_version1 = Version.find_by_id(change_params[:fixed_version_id][0])
|
||||
fix_version2 = Version.find_by_id(change_params[:fixed_version_id][1])
|
||||
|
|
@ -267,7 +267,7 @@ class MessageTemplate::IssueChanged < MessageTemplate
|
|||
else
|
||||
content.gsub!(/({ifmilestone})(.*)({endmilestone})/, '')
|
||||
end
|
||||
# 易修标记修改
|
||||
# 疑修标记修改
|
||||
if change_params[:issue_tags_value].present?
|
||||
issue_tags1 = IssueTag.where(id: change_params[:issue_tags_value][0]).distinct
|
||||
issue_tags2 = IssueTag.where(id: change_params[:issue_tags_value][1]).distinct
|
||||
|
|
@ -284,7 +284,7 @@ class MessageTemplate::IssueChanged < MessageTemplate
|
|||
else
|
||||
content.gsub!(/({iftag})(.*)({endtag})()/, '')
|
||||
end
|
||||
# 易修优先级修改
|
||||
# 疑修优先级修改
|
||||
if change_params[:priority_id].present?
|
||||
priority1 = IssuePriority.find_by_id(change_params[:priority_id][0])
|
||||
priority2 = IssuePriority.find_by_id(change_params[:priority_id][1])
|
||||
|
|
@ -299,7 +299,7 @@ class MessageTemplate::IssueChanged < MessageTemplate
|
|||
else
|
||||
content.gsub!(/({ifpriority})(.*)({endpriority})/, '')
|
||||
end
|
||||
# 易修完成度修改
|
||||
# 疑修完成度修改
|
||||
if change_params[:done_ratio].present?
|
||||
doneratio1 = change_params[:done_ratio][0]
|
||||
doneratio2 = change_params[:done_ratio][1]
|
||||
|
|
@ -314,7 +314,7 @@ class MessageTemplate::IssueChanged < MessageTemplate
|
|||
else
|
||||
content.gsub!(/({ifdoneratio})(.*)({enddoneratio})/, '')
|
||||
end
|
||||
# 易修指定分支修改
|
||||
# 疑修指定分支修改
|
||||
if change_params[:branch_name].present?
|
||||
branch1 = change_params[:branch_name][0].blank? ? '分支未指定' : change_params[:branch_name][0]
|
||||
branch2 = change_params[:branch_name][1].blank? ? '分支未指定' : change_params[:branch_name][1]
|
||||
|
|
@ -329,7 +329,7 @@ class MessageTemplate::IssueChanged < MessageTemplate
|
|||
else
|
||||
content.gsub!(/({ifbranch})(.*)({endbranch})/, '')
|
||||
end
|
||||
# 易修开始日期修改
|
||||
# 疑修开始日期修改
|
||||
if change_params[:start_date].present?
|
||||
startdate1 = change_params[:start_date][0].blank? ? "未选择开始日期" : change_params[:start_date][0]
|
||||
startdate2 = change_params[:start_date][1].blank? ? "未选择开始日期" : change_params[:start_date][1]
|
||||
|
|
@ -344,7 +344,7 @@ class MessageTemplate::IssueChanged < MessageTemplate
|
|||
else
|
||||
content.gsub!(/({ifstartdate})(.*)({endstartdate})/, '')
|
||||
end
|
||||
# 易修结束日期修改
|
||||
# 疑修结束日期修改
|
||||
if change_params[:due_date].present?
|
||||
duedate1 = change_params[:due_date][0].blank? ? '未选择结束日期' : change_params[:due_date][0]
|
||||
duedate2 = change_params[:due_date][1].blank? ? '未选择结束日期' : change_params[:due_date][1]
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
# email_title :string(255)
|
||||
#
|
||||
|
||||
# 我创建的易修截止日期到达最后一天
|
||||
# 我创建的疑修截止日期到达最后一天
|
||||
class MessageTemplate::IssueCreatorExpire < MessageTemplate
|
||||
|
||||
# MessageTemplate::IssueCreatorExpire.get_message_content(User.where(login: 'yystopf'), Issue.last)
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
# email_title :string(255)
|
||||
#
|
||||
|
||||
# 我创建或负责的易修删除
|
||||
# 我创建或负责的疑修删除
|
||||
class MessageTemplate::IssueDeleted < MessageTemplate
|
||||
|
||||
# MessageTemplate::IssueDeleted.get_message_content(User.where(login: 'yystopf'), User.last, "hahah")
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
# email_title :string(255)
|
||||
#
|
||||
|
||||
# TODO 我创建或负责的易修有新的评论
|
||||
# TODO 我创建或负责的疑修有新的评论
|
||||
class MessageTemplate::IssueJournal < MessageTemplate
|
||||
|
||||
# MessageTemplate::IssueJournal.get_message_content(User.where(login: 'yystopf'))
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
# email_title :string(255)
|
||||
#
|
||||
|
||||
# TODO 我管理/关注的仓库有新的易修
|
||||
# TODO 我管理/关注的仓库有新的疑修
|
||||
class MessageTemplate::ProjectIssue < MessageTemplate
|
||||
|
||||
# MessageTemplate::ProjectIssue.get_message_content(User.where(login: 'yystopf'), User.where(login: 'forgetest1'), User.last, Issue.last)
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
# 我管理的仓库项目设置被更改
|
||||
class MessageTemplate::ProjectSettingChanged < MessageTemplate
|
||||
|
||||
# MessageTemplate::ProjectSettingChanged.get_message_content(User.where(login: 'yystopf'), User.last, Project.last, {description: '测试修改项目简介', category: '大数据', language: 'Ruby', permission: '公有', navbar: '易修, 合并请求'})
|
||||
# MessageTemplate::ProjectSettingChanged.get_message_content(User.where(login: 'yystopf'), User.last, Project.last, {description: '测试修改项目简介', category: '大数据', language: 'Ruby', permission: '公有', navbar: '疑修, 合并请求'})
|
||||
def self.get_message_content(receivers, operator, project, change_params)
|
||||
receivers.each do |receiver|
|
||||
if receiver.user_template_message_setting.present?
|
||||
|
|
@ -135,7 +135,7 @@ class MessageTemplate::ProjectSettingChanged < MessageTemplate
|
|||
unit_types.unshift('主页')
|
||||
unit_types.append('动态')
|
||||
navbar = unit_types.join(',')
|
||||
navbar.gsub!('issues', '易修')
|
||||
navbar.gsub!('issues', '疑修')
|
||||
navbar.gsub!('pulls', '合并请求')
|
||||
navbar.gsub!('wiki', 'Wiki')
|
||||
navbar.gsub!('devops', '工作流')
|
||||
|
|
@ -284,7 +284,7 @@ class MessageTemplate::ProjectSettingChanged < MessageTemplate
|
|||
unit_types.unshift('主页')
|
||||
unit_types.append('动态')
|
||||
navbar = unit_types.join(',')
|
||||
navbar.gsub!('issues', '易修')
|
||||
navbar.gsub!('issues', '疑修')
|
||||
navbar.gsub!('pulls', '合并请求')
|
||||
navbar.gsub!('wiki', 'Wiki')
|
||||
navbar.gsub!('devops', '工作流')
|
||||
|
|
|
|||
|
|
@ -0,0 +1,58 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: message_templates
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# type :string(255)
|
||||
# sys_notice :text(65535)
|
||||
# email :text(65535)
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# notification_url :string(255)
|
||||
# email_title :string(255)
|
||||
#
|
||||
|
||||
# 账号被拉入组织团队
|
||||
class MessageTemplate::TeamJoined < MessageTemplate
|
||||
|
||||
# MessageTemplate::TeamJoined.get_message_content(User.where(login: 'yystopf'), Organization.last, Organization.last.teams.take)
|
||||
def self.get_message_content(receivers, organization, team)
|
||||
receivers.each do |receiver|
|
||||
if receiver.user_template_message_setting.present?
|
||||
receivers = receivers.where.not(id: receiver.id) unless receiver.user_template_message_setting.notification_body["Normal::Permission"]
|
||||
end
|
||||
end
|
||||
return '', '', '' if receivers.blank?
|
||||
content = sys_notice.gsub('{organization}', organization&.real_name).gsub('{team}', team&.nickname).gsub('{role}', team&.authorize_name)
|
||||
url = notification_url.gsub('{login}', organization&.login)
|
||||
return receivers_string(receivers), content, url
|
||||
rescue => e
|
||||
Rails.logger.info("MessageTemplate::TeamJoined.get_message_content [ERROR] #{e}")
|
||||
return '', '', ''
|
||||
end
|
||||
|
||||
def self.get_email_message_content(receiver, organization, role)
|
||||
if receiver.user_template_message_setting.present?
|
||||
return '', '', '' unless receiver.user_template_message_setting.email_body["Normal::Permission"]
|
||||
title = email_title
|
||||
title.gsub!('{organization}', organization&.real_name)
|
||||
title.gsub!('{team}', team&.nickname)
|
||||
title.gsub!('{role}', team&.authorize_name)
|
||||
content = email
|
||||
content.gsub!('{receiver}', receiver&.real_name)
|
||||
content.gsub!('{baseurl}', base_url)
|
||||
content.gsub!('{login}', organization&.login)
|
||||
content.gsub!('{organization}', organization&.real_name)
|
||||
content.gsub!('{team}', team&.nickname)
|
||||
content.gsub!('{role}', team&.authorize_name)
|
||||
|
||||
return receiver&.mail, title, content
|
||||
else
|
||||
return '', '', ''
|
||||
end
|
||||
|
||||
rescue => e
|
||||
Rails.logger.info("MessageTemplate::TeamJoined.get_email_message_content [ERROR] #{e}")
|
||||
return '', '', ''
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: message_templates
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# type :string(255)
|
||||
# sys_notice :text(65535)
|
||||
# email :text(65535)
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# notification_url :string(255)
|
||||
# email_title :string(255)
|
||||
#
|
||||
|
||||
# 账号被移出组织团队
|
||||
class MessageTemplate::TeamLeft < MessageTemplate
|
||||
|
||||
# MessageTemplate::TeamLeft.get_message_content(User.where(login: 'yystopf'), Organization.last, Organization.last.teams.take)
|
||||
def self.get_message_content(receivers, organization, team)
|
||||
receivers.each do |receiver|
|
||||
if receiver.user_template_message_setting.present?
|
||||
receivers = receivers.where.not(id: receiver.id) unless receiver.user_template_message_setting.notification_body["Normal::Permission"]
|
||||
end
|
||||
end
|
||||
return '', '', '' if receivers.blank?
|
||||
content = sys_notice.gsub('{organization}', organization&.real_name).gsub('{team}', team&.nickname).gsub('{role}', team&.authorize_name)
|
||||
url = notification_url.gsub('{login}', organization&.login)
|
||||
return receivers_string(receivers), content, url
|
||||
rescue => e
|
||||
Rails.logger.info("MessageTemplate::TeamLeft.get_message_content [ERROR] #{e}")
|
||||
return '', '', ''
|
||||
end
|
||||
|
||||
def self.get_email_message_content(receiver, organization, team)
|
||||
if receiver.user_template_message_setting.present?
|
||||
return '', '', '' unless receiver.user_template_message_setting.email_body["Normal::Permission"]
|
||||
title = email_title
|
||||
title.gsub!('{organization}', organization&.real_name)
|
||||
title.gsub!('{team}', team&.nickname)
|
||||
title.gsub!('{role}', team&.authorize_name)
|
||||
content = email
|
||||
content.gsub!('{receiver}', receiver&.real_name)
|
||||
content.gsub!('{baseurl}', base_url)
|
||||
content.gsub!('{login}', organization&.login)
|
||||
content.gsub!('{organization}', organization&.real_name)
|
||||
content.gsub!('{team}', team&.nickname)
|
||||
content.gsub!('{role}', team&.authorize_name)
|
||||
|
||||
return receiver&.mail, title, content
|
||||
else
|
||||
return '', '', ''
|
||||
end
|
||||
|
||||
rescue => e
|
||||
Rails.logger.info("MessageTemplate::TeamLeft.get_email_message_content [ERROR] #{e}")
|
||||
return '', '', ''
|
||||
end
|
||||
end
|
||||
|
|
@ -56,10 +56,10 @@ class Team < ApplicationRecord
|
|||
|
||||
def authorize_name
|
||||
case self.authorize
|
||||
when 'read' then '报告者'
|
||||
when 'write' then '开发者'
|
||||
when 'read' then '读取'
|
||||
when 'write' then '写入'
|
||||
when 'admin' then '管理员'
|
||||
when 'owner' then '拥有者'
|
||||
when 'owner' then '管理员'
|
||||
else
|
||||
''
|
||||
end
|
||||
|
|
|
|||
|
|
@ -22,9 +22,17 @@ class TeamUser < ApplicationRecord
|
|||
belongs_to :team, counter_cache: :num_users
|
||||
belongs_to :user
|
||||
|
||||
has_one :member
|
||||
|
||||
validates :user_id, uniqueness: {scope: [:organization_id, :team_id]}
|
||||
|
||||
before_destroy :remove_project_member
|
||||
|
||||
def self.build(organization_id, user_id, team_id)
|
||||
self.create!(organization_id: organization_id, user_id: user_id, team_id: team_id)
|
||||
end
|
||||
|
||||
def remove_project_member
|
||||
member.destroy if member.present?
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ class TemplateMessageSetting::CreateOrAssign < TemplateMessageSetting
|
|||
end
|
||||
|
||||
def self.build_init_data
|
||||
self.find_or_create_by(name: "易修状态变更", key: "IssueChanged")
|
||||
self.find_or_create_by(name: "疑修状态变更", key: "IssueChanged")
|
||||
self.find_or_create_by(name: "合并请求状态变更", key: "PullRequestChanged")
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ class TemplateMessageSetting::ManageProject < TemplateMessageSetting
|
|||
end
|
||||
|
||||
def self.build_init_data
|
||||
self.find_or_create_by(name: "有新的易修", key: "Issue")
|
||||
self.find_or_create_by(name: "有新的疑修", key: "Issue")
|
||||
self.find_or_create_by(name: "有新的合并请求", key: "PullRequest")
|
||||
self.find_or_create_by(name: "有成员变动", key: "Member")
|
||||
self.find_or_create_by(name: "仓库设置被更改", key: "SettingChanged")
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ class TemplateMessageSetting::Normal < TemplateMessageSetting
|
|||
self.find_or_create_by(name: "账号有权限变更", key: "Permission")
|
||||
self.find_or_create_by(name: "被拉入或移出组织", key: "Organization")
|
||||
self.find_or_create_by(name: "被拉入或移出项目", key: "Project")
|
||||
self.find_or_create_by(name: "有新的易修指派给我", key: "IssueAssigned")
|
||||
self.find_or_create_by(name: "有新的疑修指派给我", key: "IssueAssigned")
|
||||
self.find_or_create_by(name: "有新的合并请求指派给我", key: "PullRequestAssigned")
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -786,7 +786,7 @@ class User < Owner
|
|||
end
|
||||
|
||||
def profile_is_completed?
|
||||
self.nickname.present? && self.gender.present? && self.mail.present? && self.custom_department.present?
|
||||
self.nickname.present? && self.mail.present?
|
||||
end
|
||||
|
||||
protected
|
||||
|
|
|
|||
|
|
@ -32,6 +32,6 @@ class AtmeService < ApplicationService
|
|||
else
|
||||
return
|
||||
end
|
||||
SendTemplateMessageJob.perform_now(message_source, receivers, user.id, @atmeable.id) if Site.has_notice_menu?
|
||||
SendTemplateMessageJob.perform_later(message_source, receivers.pluck(:id), user.id, @atmeable.id) if Site.has_notice_menu?
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ class Gitea::Organization::UpdateService < Gitea::ClientService
|
|||
def request_params
|
||||
update_params = {
|
||||
name: org.login,
|
||||
full_name: org.nickname,
|
||||
description: org.description,
|
||||
location: org.location,
|
||||
repo_admin_change_team_access: org.repo_admin_change_team_access,
|
||||
|
|
|
|||
|
|
@ -55,7 +55,12 @@ class Gitea::Repository::Entries::CreateService < Gitea::ClientService
|
|||
when 201 then success(json_parse!(body))
|
||||
when 403 then error("你没有权限操作!")
|
||||
when 404 then error("你操作的链接不存在!")
|
||||
when 422 then error("#{filepath}文件已存在,不能重复创建!")
|
||||
when 422
|
||||
if @body[:new_branch].include?('/') || @body[:new_branch].include?('\'') || @body[:new_branch].include?('^') || @body[:new_branch].include?('*')
|
||||
error("不合法的分支名称!")
|
||||
else
|
||||
error("#{filepath}文件已存在,不能重复创建!")
|
||||
end
|
||||
else error("系统错误!")
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -59,6 +59,8 @@ class Notice::Write::ClientService < ApplicationService
|
|||
req.request :url_encoded
|
||||
req.headers['Content-Type'] = 'application/json'
|
||||
req.adapter Faraday.default_adapter
|
||||
req.options.timeout = 100 # open/read timeout in seconds
|
||||
req.options.open_timeout = 10 # connection open timeout in seconds
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -148,6 +148,7 @@ class PullRequests::CreateService < ApplicationService
|
|||
|
||||
def validate!
|
||||
raise "title参数不能为空" if @params[:title].blank?
|
||||
raise "title不能超过255个字符" if @params[:title].length > 255
|
||||
raise "head参数不能为空" if @params[:head].blank?
|
||||
raise "base参数不能为空" if @params[:base].blank?
|
||||
raise "fork_project_id参数错误" if is_original && !@project.forked_projects.pluck(:id).include?(@params[:fork_project_id].to_i)
|
||||
|
|
|
|||
|
|
@ -10,20 +10,12 @@ class Repositories::DetailService < ApplicationService
|
|||
def call
|
||||
return {
|
||||
repo: repo_suitable,
|
||||
contributor: contributor_suitable,
|
||||
language: language_suitable,
|
||||
branch_tag_total_count: branch_tag_total_count
|
||||
}
|
||||
rescue
|
||||
return {
|
||||
repo: {},
|
||||
release: [],
|
||||
branch: [],
|
||||
branch_type: [],
|
||||
tag: [],
|
||||
contributor: [],
|
||||
language: {},
|
||||
readme: {}
|
||||
branch_tag_total_count: {}
|
||||
}
|
||||
end
|
||||
|
||||
|
|
@ -35,14 +27,4 @@ class Repositories::DetailService < ApplicationService
|
|||
def repo_suitable
|
||||
Gitea::Repository::GetService.call(@owner, @repo.identifier)
|
||||
end
|
||||
|
||||
def contributor_suitable
|
||||
contributors = Gitea::Repository::Contributors::GetService.call(@owner, @repo.identifier)
|
||||
contributors.is_a?(Hash) && contributors.key?(:status) ? [] : contributors
|
||||
end
|
||||
|
||||
def language_suitable
|
||||
result = Gitea::Repository::Languages::ListService.call(@owner.login, @repo.identifier, @user&.gitea_token)
|
||||
result[:status] === :success ? hash_transform_precentagable(result[:body]) : nil
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
json.user_name claimer.user.try(:show_real_name)
|
||||
json.user_login claimer.user.try(:login)
|
||||
json.user_picture url_to_avatar(claimer.user)
|
||||
json.created_at time_from_now(claimer.created_at)
|
||||
json.note_body claimer.note
|
||||
json.claim_id claimer.id
|
||||
json.visible false
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
json.partial! "commons/success"
|
||||
json.currentUserclaimed @user_claimed
|
||||
json.claimers do
|
||||
json.array! @claims do |claimer|
|
||||
json.partial! "claims/claim_item", claimer: claimer
|
||||
end
|
||||
end
|
||||
|
|
@ -13,6 +13,7 @@ json.tracker @issue.tracker.try(:name)
|
|||
json.issue_status @issue.issue_status.try(:name)
|
||||
json.priority @issue.priority.try(:name)
|
||||
json.version @issue.version.try(:name)
|
||||
json.version_id @issue.version.try(:id)
|
||||
json.issue_tags @issue.get_issue_tags
|
||||
json.done_ratio @issue.done_ratio.to_s + "%"
|
||||
json.issue_type @issue.issue_type
|
||||
|
|
|
|||
|
|
@ -3,15 +3,26 @@ owner_common = $redis_cache.hgetall("v2-owner-common:#{project_common["owner_id"
|
|||
json.id item[0]
|
||||
json.score item[1]
|
||||
json.name project_common["name"]
|
||||
json.identifier project_common["identifier"]
|
||||
json.description project_common["description"]
|
||||
json.owner do
|
||||
json.id project_common["owner_id"]
|
||||
json.type owner_common["type"]
|
||||
json.name owner_common["name"]
|
||||
json.login owner_common["login"]
|
||||
json.avatar_url owner_common["avatar_url"]
|
||||
if project_common['identifier'].include?("/")
|
||||
json.identifier project_common["identifier"].split('/')[1]
|
||||
json.owner do
|
||||
json.id nil
|
||||
json.type 'User'
|
||||
json.name project_common["identifier"].split('/')[0]
|
||||
json.login project_common["identifier"].split('/')[0]
|
||||
json.avatar_url User::Avatar.get_letter_avatar_url(project_common["identifier"].split('/')[0])
|
||||
end
|
||||
else
|
||||
json.identifier project_common["identifier"]
|
||||
json.owner do
|
||||
json.id project_common["owner_id"]
|
||||
json.type owner_common["type"]
|
||||
json.name owner_common["name"]
|
||||
json.login owner_common["login"]
|
||||
json.avatar_url owner_common["avatar_url"]
|
||||
end
|
||||
end
|
||||
json.description project_common["description"]
|
||||
json.visits project_common["visits"]
|
||||
json.forks project_common["forks"]
|
||||
json.watchers project_common["watchers"]
|
||||
|
|
|
|||
|
|
@ -6,6 +6,13 @@ json.user_name trend.user.try(:show_real_name)
|
|||
json.user_login trend.user.login
|
||||
json.user_avatar url_to_avatar(trend.user)
|
||||
json.action_time time_from_now(trend.created_at)
|
||||
json.project do
|
||||
json.owner do
|
||||
json.partial! 'users/user_simple', locals: {user: trend&.project&.owner}
|
||||
end
|
||||
json.identifier trend&.project&.identifier
|
||||
json.description trend&.project&.description
|
||||
end
|
||||
|
||||
if trend.trend_type == "Issue"
|
||||
json.partial! "issues/simple_issue_item", locals: {issue: trend.trend}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,27 @@
|
|||
json.author do
|
||||
json.partial! 'repositories/commit_author', locals: { user: render_cache_commit_author(commit['Author']), name: commit['Author']['Name'] }
|
||||
end
|
||||
if commit['Status'].present?
|
||||
json.author do
|
||||
json.partial! 'repositories/commit_author', locals: { user: render_cache_commit_author(commit['Author']), name: commit['Author']['Name'] }
|
||||
end
|
||||
|
||||
json.committer do
|
||||
json.partial! 'repositories/commit_author', locals: { user: render_cache_commit_author(commit['Committer']), name: commit['Committer']['Name'] }
|
||||
end
|
||||
json.timestamp render_unix_time(commit['Committer']['When'])
|
||||
json.time_from_now time_from_now(commit['Committer']['When'])
|
||||
json.created_at render_format_time_with_date(commit['Committer']['When'])
|
||||
json.message commit['CommitMessage']
|
||||
json.sha commit['Sha']
|
||||
else
|
||||
json.author do
|
||||
json.partial! 'repositories/commit_author', locals: { user: render_cache_commit_author(commit['commit']['author']), name: commit['commit']['author']['name'] }
|
||||
end
|
||||
|
||||
json.committer do
|
||||
json.partial! 'repositories/commit_author', locals: { user: render_cache_commit_author(commit['Committer']), name: commit['Committer']['Name'] }
|
||||
end
|
||||
json.timestamp render_unix_time(commit['Committer']['When'])
|
||||
json.time_from_now time_from_now(commit['Committer']['When'])
|
||||
json.created_at render_format_time_with_date(commit['Committer']['When'])
|
||||
json.message commit['CommitMessage']
|
||||
json.sha commit['Sha']
|
||||
json.committer do
|
||||
json.partial! 'repositories/commit_author', locals: { user: render_cache_commit_author(commit['commit']['committer']), name: commit['commit']['committer']['name'] }
|
||||
end
|
||||
json.timestamp render_unix_time(commit['commit']['committer']['date'])
|
||||
json.time_from_now time_from_now(commit['commit']['committer']['date'])
|
||||
json.created_at render_format_time_with_date(commit['commit']['committer']['date'])
|
||||
json.message commit['commit']['message']
|
||||
json.sha commit['sha']
|
||||
end
|
||||
|
|
@ -7,11 +7,22 @@ if @project.educoder?
|
|||
json.timestamp 0
|
||||
json.time_from_now commit[0]['time']
|
||||
end
|
||||
json.author do
|
||||
{}
|
||||
# json.partial! '/projects/author', user: render_commit_author(commit['author'])
|
||||
end
|
||||
json.committer {}
|
||||
if commit[0]['author'].present?
|
||||
json.author do
|
||||
json.id nil
|
||||
json.login commit[0]['author']['username']
|
||||
json.name commit[0]['author']['username']
|
||||
json.type nil
|
||||
json.image_url commit[0]['author']['image_url']
|
||||
end
|
||||
json.committer do
|
||||
json.id nil
|
||||
json.login commit[0]['author']['username']
|
||||
json.name commit[0]['author']['username']
|
||||
json.type nil
|
||||
json.image_url commit[0]['author']['image_url']
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if @project.forge?
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@ end
|
|||
|
||||
if @project.educoder?
|
||||
file_path = params[:filepath].present? ? [params[:filepath], entry['name']].join('/') : entry['name']
|
||||
file_type = File.extname(entry['name'].to_s)[1..-1]
|
||||
image_type = image_type?(file_type)
|
||||
|
||||
json.name entry['name']
|
||||
json.sha nil
|
||||
|
|
@ -42,7 +44,7 @@ if @project.educoder?
|
|||
json.target nil
|
||||
json.download_url nil
|
||||
json.direct_download false
|
||||
json.image_type false
|
||||
json.image_type image_type
|
||||
json.is_readme_file false
|
||||
json.commit do
|
||||
json.message entry['title']
|
||||
|
|
|
|||
|
|
@ -1,6 +1,26 @@
|
|||
if @hash_commit.blank? #如果有状态值,则表示报错了
|
||||
if @hash_commit.blank? || @project.educoder? #如果有状态值,则表示报错了
|
||||
json.total_count 0
|
||||
json.commits []
|
||||
json.commits do
|
||||
json.array! @commits do |commit|
|
||||
json.sha commit['id']
|
||||
json.message commit['title']
|
||||
json.time_from_now commit['time']
|
||||
json.author do
|
||||
json.id nil
|
||||
json.login commit['author']['username']
|
||||
json.name commit['author']['username']
|
||||
json.type nil
|
||||
json.image_url commit['author']['image_url']
|
||||
end
|
||||
json.committer do
|
||||
json.id nil
|
||||
json.login commit['author']['username']
|
||||
json.name commit['author']['username']
|
||||
json.type nil
|
||||
json.image_url commit['author']['image_url']
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
json.total_count @hash_commit[:total_count]
|
||||
json.commits do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
total_count = @contributors.size
|
||||
json.contributors @contributors.each do |contributor|
|
||||
json.list @contributors.each do |contributor|
|
||||
json.partial! 'contributor', locals: { contributor: contributor }
|
||||
end
|
||||
json.total_count total_count
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ end
|
|||
if @result[:repo]
|
||||
json.size replace_bytes_to_b(number_to_human_size(@result[:repo]['size'].to_i*1024))
|
||||
json.ssh_url @result[:repo]['ssh_url']
|
||||
json.clone_url @result[:repo]['clone_url']
|
||||
json.clone_url @project.educoder? ? "#{Rails.application.config_for(:configuration)['educoder']['git_site']}/#{@project&.project_educoder&.repo_name}.git" : @result[:repo]['clone_url']
|
||||
json.default_branch @project.educoder? ? "master" : @result[:repo]['default_branch']
|
||||
json.empty @result[:repo]['empty']
|
||||
json.full_name @result[:repo]['full_name']
|
||||
|
|
@ -53,13 +53,13 @@ end
|
|||
json.license_name @project.license_name
|
||||
json.branches_count @result[:branch_tag_total_count].present? ? (@result[:branch_tag_total_count]['branch_count'] || 0) : 0
|
||||
json.tags_count @result[:branch_tag_total_count].present? ? (@result[:branch_tag_total_count]['tag_count'] || 0) : 0
|
||||
json.contributors do
|
||||
total_count = @result[:contributor].size
|
||||
json.list @result[:contributor].each do |contributor|
|
||||
json.partial! 'contributor', locals: { contributor: contributor }
|
||||
end
|
||||
json.total_count total_count
|
||||
end
|
||||
json.languages @result[:language].blank? ? nil : @result[:language]
|
||||
# json.contributors do
|
||||
# total_count = @result[:contributor].size
|
||||
# json.list @result[:contributor].each do |contributor|
|
||||
# json.partial! 'contributor', locals: { contributor: contributor }
|
||||
# end
|
||||
# json.total_count total_count
|
||||
# end
|
||||
# json.languages @result[:language].blank? ? nil : @result[:language]
|
||||
|
||||
json.partial! 'author', locals: { user: @project.owner }
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ if @project.educoder?
|
|||
end
|
||||
end
|
||||
json.commits_count @entries['commit_count']
|
||||
json.zip_url @entries['git_url']
|
||||
json.zip_url ''
|
||||
json.tar_url ''
|
||||
json.entries do
|
||||
json.array! @entries['trees'] do |entry|
|
||||
|
|
|
|||
|
|
@ -24,8 +24,12 @@ if @project.educoder?
|
|||
end
|
||||
end
|
||||
json.entries do
|
||||
json.array! @sub_entries['trees'] do |entry|
|
||||
json.partial! 'repositories/simple_entry', locals: { entry: entry }
|
||||
if @sub_entries['trees'].is_a?(Array)
|
||||
json.array! @sub_entries['trees'] do |entry|
|
||||
json.partial! 'repositories/simple_entry', locals: { entry: entry }
|
||||
end
|
||||
elsif @sub_entries['trees'].is_a?(Hash)
|
||||
json.partial! 'repositories/simple_entry', locals: { entry: @sub_entries['trees'] }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ zh-CN:
|
|||
'refused': '已拒绝'
|
||||
'agreed': '已同意'
|
||||
trend:
|
||||
Issue: 易修(Issue)
|
||||
Issue: 疑修(Issue)
|
||||
PullRequest: 合并请求(PR)
|
||||
VersionRelease: 版本发布
|
||||
create: 创建了
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ Rails.application.routes.draw do
|
|||
# Serve websocket cable requests in-process
|
||||
mount ActionCable.server => '/cable'
|
||||
|
||||
|
||||
get 'attachments/entries/get_file', to: 'attachments#get_file'
|
||||
get 'attachments/download/:id', to: 'attachments#show'
|
||||
get 'attachments/download/:id/:filename', to: 'attachments#show'
|
||||
|
|
@ -146,6 +147,16 @@ Rails.application.routes.draw do
|
|||
get :get_children_journals
|
||||
end
|
||||
end
|
||||
|
||||
resources :claims, only: [:index] do
|
||||
collection do
|
||||
post :create
|
||||
delete :destroy
|
||||
get :index
|
||||
put :update
|
||||
end
|
||||
end
|
||||
|
||||
resources :issue_times, only: [:create] do
|
||||
collection do
|
||||
post :end_work
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
class CreateClaims < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
create_table :claims do |t|
|
||||
t.integer :issue_id
|
||||
t.integer :user_id
|
||||
t.timestamps
|
||||
t.index :issue_id
|
||||
t.index :user_id
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
class AddNoteToClaim < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
add_column :claims, :note, :text
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
class AddTeamUserToMembers < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
add_reference :members, :team_user
|
||||
end
|
||||
end
|
||||
2
dir.md
2
dir.md
|
|
@ -87,7 +87,7 @@ forgeplus
|
|||
│ │ │ │ └── tags(标签)
|
||||
│ │ │ ├── user(用户)
|
||||
│ │ │ └── versions(发行版)
|
||||
│ │ ├── issues(易修)
|
||||
│ │ ├── issues(疑修)
|
||||
│ │ ├── libraries
|
||||
│ │ ├── oauth
|
||||
│ │ ├── organizations(组织)
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
|
|
@ -1138,31 +1138,31 @@ Success — a happy kitten is an authenticated kitten!
|
|||
</thead><tbody>
|
||||
<tr>
|
||||
<td>IssueAssigned</td>
|
||||
<td>有新指派给我的易修</td>
|
||||
<td>有新指派给我的疑修</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>IssueAssignerExpire</td>
|
||||
<td>我负责的易修截止日期到达最后一天</td>
|
||||
<td>我负责的疑修截止日期到达最后一天</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>IssueAtme</td>
|
||||
<td>在易修中@我</td>
|
||||
<td>在疑修中@我</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>IssueChanged</td>
|
||||
<td>我创建或负责的易修状态变更</td>
|
||||
<td>我创建或负责的疑修状态变更</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>IssueCreatorExpire</td>
|
||||
<td>我创建的易修截止日期到达最后一天</td>
|
||||
<td>我创建的疑修截止日期到达最后一天</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>IssueDeleted</td>
|
||||
<td>我创建或负责的易修删除</td>
|
||||
<td>我创建或负责的疑修删除</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>IssueJournal</td>
|
||||
<td>我创建或负责的易修有新的评论</td>
|
||||
<td>我创建或负责的疑修有新的评论</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>LoginIpTip</td>
|
||||
|
|
@ -1194,7 +1194,7 @@ Success — a happy kitten is an authenticated kitten!
|
|||
</tr>
|
||||
<tr>
|
||||
<td>ProjectIssue</td>
|
||||
<td>我管理/关注的仓库有新的易修</td>
|
||||
<td>我管理/关注的仓库有新的疑修</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>ProjectJoined</td>
|
||||
|
|
@ -1403,7 +1403,7 @@ Success — a happy kitten is an authenticated kitten!
|
|||
<tr>
|
||||
<td>atmeable_type</td>
|
||||
<td>string</td>
|
||||
<td>atme消息对象,是从哪里@我的,比如评论:Journal、易修:Issue、合并请求:PullRequest</td>
|
||||
<td>atme消息对象,是从哪里@我的,比如评论:Journal、疑修:Issue、合并请求:PullRequest</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>atmeable_id</td>
|
||||
|
|
@ -1706,7 +1706,7 @@ Success — a happy kitten is an authenticated kitten!
|
|||
</span><span class="nl">"total_settings_count"</span><span class="p">:</span><span class="w"> </span><span class="mi">4</span><span class="p">,</span><span class="w">
|
||||
</span><span class="nl">"settings"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
|
||||
</span><span class="p">{</span><span class="w">
|
||||
</span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"易修被指派"</span><span class="p">,</span><span class="w">
|
||||
</span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"疑修被指派"</span><span class="p">,</span><span class="w">
|
||||
</span><span class="nl">"key"</span><span class="p">:</span><span class="w"> </span><span class="s2">"IssueAssigned"</span><span class="p">,</span><span class="w">
|
||||
</span><span class="nl">"notification_disabled"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
|
||||
</span><span class="nl">"email_disabled"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w">
|
||||
|
|
@ -1725,7 +1725,7 @@ Success — a happy kitten is an authenticated kitten!
|
|||
</span><span class="nl">"total_settings_count"</span><span class="p">:</span><span class="w"> </span><span class="mi">4</span><span class="p">,</span><span class="w">
|
||||
</span><span class="nl">"settings"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
|
||||
</span><span class="p">{</span><span class="w">
|
||||
</span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"有新的易修"</span><span class="p">,</span><span class="w">
|
||||
</span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"有新的疑修"</span><span class="p">,</span><span class="w">
|
||||
</span><span class="nl">"key"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Issue"</span><span class="p">,</span><span class="w">
|
||||
</span><span class="nl">"notification_disabled"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
|
||||
</span><span class="nl">"email_disabled"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w">
|
||||
|
|
@ -2245,7 +2245,7 @@ Success — a happy kitten is an authenticated kitten!
|
|||
<tr>
|
||||
<td>issues_count</td>
|
||||
<td>array</td>
|
||||
<td>易修数量</td>
|
||||
<td>疑修数量</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>pull_requests_count</td>
|
||||
|
|
@ -2493,7 +2493,7 @@ Success — a happy kitten is an authenticated kitten!
|
|||
<tr>
|
||||
<td>project_trends.trend_type</td>
|
||||
<td>string</td>
|
||||
<td>动态类型,Issue:易修,VersionRelease:版本发布,PullRequest:合并请求</td>
|
||||
<td>动态类型,Issue:疑修,VersionRelease:版本发布,PullRequest:合并请求</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>project_trends.action_type</td>
|
||||
|
|
@ -4968,7 +4968,7 @@ http://localhost:3000/api/yystopf/ceshi/menu_list | jq
|
|||
<tr>
|
||||
<td>menu_name</td>
|
||||
<td>string</td>
|
||||
<td>导航名称, home:主页,code:代码库,issues:易修,pulls:合并请求,devops:工作流,versions:里程碑,activity:动态,setting:仓库设置</td>
|
||||
<td>导航名称, home:主页,code:代码库,issues:疑修,pulls:合并请求,devops:工作流,versions:里程碑,activity:动态,setting:仓库设置</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
|
||||
|
|
@ -5131,7 +5131,7 @@ http://localhost:3000/api/yystopf/ceshi/project_units.json
|
|||
<td>是</td>
|
||||
<td></td>
|
||||
<td>array</td>
|
||||
<td>项目模块内容, 支持以下参数:code:代码库,issues:易修,pulls:合并请求,devops:工作流,versions:里程碑</td>
|
||||
<td>项目模块内容, 支持以下参数:code:代码库,issues:疑修,pulls:合并请求,devops:工作流,versions:里程碑</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<h3 id='7447e4874e-2'>返回字段说明:</h3>
|
||||
|
|
@ -8346,23 +8346,23 @@ http://localhost:3000/api/yystopf/ceshi/webhooks/3/edit.json
|
|||
</tr>
|
||||
<tr>
|
||||
<td>issue</td>
|
||||
<td>易修已打开、已关闭、已重新打开或编辑</td>
|
||||
<td>疑修已打开、已关闭、已重新打开或编辑</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>issue_assign</td>
|
||||
<td>易修被指派</td>
|
||||
<td>疑修被指派</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>issue_label</td>
|
||||
<td>易修标签被更新或删除</td>
|
||||
<td>疑修标签被更新或删除</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>issue_milestone</td>
|
||||
<td>易修被收入里程碑</td>
|
||||
<td>疑修被收入里程碑</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>issue_comment</td>
|
||||
<td>易修评论</td>
|
||||
<td>疑修评论</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>pull_request</td>
|
||||
|
|
@ -8568,23 +8568,23 @@ http://localhost:3000/api/yystopf/ceshi/webhooks.json
|
|||
</tr>
|
||||
<tr>
|
||||
<td>issue</td>
|
||||
<td>易修已打开、已关闭、已重新打开或编辑</td>
|
||||
<td>疑修已打开、已关闭、已重新打开或编辑</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>issue_assign</td>
|
||||
<td>易修被指派</td>
|
||||
<td>疑修被指派</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>issue_label</td>
|
||||
<td>易修标签被更新或删除</td>
|
||||
<td>疑修标签被更新或删除</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>issue_milestone</td>
|
||||
<td>易修被收入里程碑</td>
|
||||
<td>疑修被收入里程碑</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>issue_comment</td>
|
||||
<td>易修评论</td>
|
||||
<td>疑修评论</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>pull_request</td>
|
||||
|
|
@ -8833,23 +8833,23 @@ http://localhost:3000/api/yystopf/ceshi/webhooks/7.json
|
|||
</tr>
|
||||
<tr>
|
||||
<td>issue</td>
|
||||
<td>易修已打开、已关闭、已重新打开或编辑</td>
|
||||
<td>疑修已打开、已关闭、已重新打开或编辑</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>issue_assign</td>
|
||||
<td>易修被指派</td>
|
||||
<td>疑修被指派</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>issue_label</td>
|
||||
<td>易修标签被更新或删除</td>
|
||||
<td>疑修标签被更新或删除</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>issue_milestone</td>
|
||||
<td>易修被收入里程碑</td>
|
||||
<td>疑修被收入里程碑</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>issue_comment</td>
|
||||
<td>易修评论</td>
|
||||
<td>疑修评论</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>pull_request</td>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>有新的易修指派给我</title>
|
||||
<title>有新的疑修指派给我</title>
|
||||
<style type="text/css">
|
||||
body,h1,h2,h3,h4,h5,h6,hr,p,blockquote,dl,dt,dd,ul,ol,li,pre,form,fieldset,legend,button,input,textarea,th,td{ margin:0; padding:0;}
|
||||
body,table,input,textarea,select,button { font-family: "微软雅黑","宋体"; font-size:12px;line-height:1.5; background:#eaebec;}
|
||||
|
|
@ -31,7 +31,7 @@
|
|||
<div style="width: 558px; border-left:1px solid #ddd;border-right:1px solid #ddd; background:#fff; padding:20px; color:#333; line-height: 1.9;">
|
||||
<p style="font-size: 14px; color:#333;">
|
||||
{receiver},您好!<br/>
|
||||
<a href="{baseurl}/{login1}" style="font-weight:bold;color:#3b94d6;">{nickname1}</a>在 {nickname2}/{repository} 指派给你一个易修:<a href="{baseurl}/{login2}/{identifier}/issues/{id}" style="font-weight:bold;color:#3b94d6;">{title}</a><br/>
|
||||
<a href="{baseurl}/{login1}" style="font-weight:bold;color:#3b94d6;">{nickname1}</a>在 {nickname2}/{repository} 指派给你一个疑修:<a href="{baseurl}/{login2}/{identifier}/issues/{id}" style="font-weight:bold;color:#3b94d6;">{title}</a><br/>
|
||||
</p>
|
||||
<div style="width: 100%; border-top: 1px solid #ddd; margin:10px 0;"></div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>有新的易修指派给我</title>
|
||||
<title>有新的疑修指派给我</title>
|
||||
<style type="text/css">
|
||||
body,h1,h2,h3,h4,h5,h6,hr,p,blockquote,dl,dt,dd,ul,ol,li,pre,form,fieldset,legend,button,input,textarea,th,td{ margin:0; padding:0;}
|
||||
body,table,input,textarea,select,button { font-family: "微软雅黑","宋体"; font-size:12px;line-height:1.5; background:#eaebec;}
|
||||
|
|
@ -31,7 +31,7 @@
|
|||
<div style="width: 558px; border-left:1px solid #ddd;border-right:1px solid #ddd; background:#fff; padding:20px; color:#333; line-height: 1.9;">
|
||||
<p style="font-size: 14px; color:#333;">
|
||||
{receiver},您好!<br/>
|
||||
在项目 <a href="{baseurl}/{login2}/{identifier}" style="font-weight:bold;color:#3b94d6;">{nickname2}/{repository}</a> 的易修 <a href="{baseurl}/{login2}/{identifier}/issues/{id}" style="font-weight:bold;color:#3b94d6;">{title}</a> 中:
|
||||
在项目 <a href="{baseurl}/{login2}/{identifier}" style="font-weight:bold;color:#3b94d6;">{nickname2}/{repository}</a> 的疑修 <a href="{baseurl}/{login2}/{identifier}/issues/{id}" style="font-weight:bold;color:#3b94d6;">{title}</a> 中:
|
||||
{ifassigner}<a href="{baseurl}/{login1}" style="font-weight:bold;color:#3b94d6;">{nickname1}</a>将负责人从 {assigner1} 修改为 {assigner2}{endassigner}
|
||||
{ifstatus}<a href="{baseurl}/{login1}" style="font-weight:bold;color:#3b94d6;">{nickname1}</a>将状态从 {status1} 修改为 {status2}{endstatus}
|
||||
{iftracker}<a href="{baseurl}/{login1}" style="font-weight:bold;color:#3b94d6;">{nickname1}</a>将类型从 {tracker1} 修改为 {tracker2}{endtracker}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>易修状态改变</title>
|
||||
<title>疑修状态改变</title>
|
||||
<style type="text/css">
|
||||
body,h1,h2,h3,h4,h5,h6,hr,p,blockquote,dl,dt,dd,ul,ol,li,pre,form,fieldset,legend,button,input,textarea,th,td{ margin:0; padding:0;}
|
||||
body,table,input,textarea,select,button { font-family: "微软雅黑","宋体"; font-size:12px;line-height:1.5; background:#eaebec;}
|
||||
|
|
@ -31,7 +31,7 @@
|
|||
<div style="width: 558px; border-left:1px solid #ddd;border-right:1px solid #ddd; background:#fff; padding:20px; color:#333; line-height: 1.9;">
|
||||
<p style="font-size: 14px; color:#333;">
|
||||
{receiver},您好!<br/>
|
||||
<a href="{baseurl}/{login}" style="font-weight:bold;color:#3b94d6;">{nickname}</a>已将易修 {title} 删除
|
||||
<a href="{baseurl}/{login}" style="font-weight:bold;color:#3b94d6;">{nickname}</a>已将疑修 {title} 删除
|
||||
</p>
|
||||
<div style="width: 100%; border-top: 1px solid #ddd; margin:10px 0;"></div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>管理的仓库有新的易修</title>
|
||||
<title>管理的仓库有新的疑修</title>
|
||||
<style type="text/css">
|
||||
body,h1,h2,h3,h4,h5,h6,hr,p,blockquote,dl,dt,dd,ul,ol,li,pre,form,fieldset,legend,button,input,textarea,th,td{ margin:0; padding:0;}
|
||||
body,table,input,textarea,select,button { font-family: "微软雅黑","宋体"; font-size:12px;line-height:1.5; background:#eaebec;}
|
||||
|
|
@ -31,7 +31,7 @@
|
|||
<div style="width: 558px; border-left:1px solid #ddd;border-right:1px solid #ddd; background:#fff; padding:20px; color:#333; line-height: 1.9;">
|
||||
<p style="font-size: 14px; color:#333;">
|
||||
{receiver},您好!<br/>
|
||||
<a href="{baseurl}/{login1}" style="font-weight:bold;color:#3b94d6;">{nickname1}</a>在 {nickname2}/{repository} 新建了一个易修:<a href="{baseurl}/{login2}/{identifier}/issues/{id}" style="font-weight:bold;color:#3b94d6;">{title}</a><br/>
|
||||
<a href="{baseurl}/{login1}" style="font-weight:bold;color:#3b94d6;">{nickname1}</a>在 {nickname2}/{repository} 新建了一个疑修:<a href="{baseurl}/{login2}/{identifier}/issues/{id}" style="font-weight:bold;color:#3b94d6;">{title}</a><br/>
|
||||
</p>
|
||||
<div style="width: 100%; border-top: 1px solid #ddd; margin:10px 0;"></div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>被拉入组织团队</title>
|
||||
<style type="text/css">
|
||||
body,h1,h2,h3,h4,h5,h6,hr,p,blockquote,dl,dt,dd,ul,ol,li,pre,form,fieldset,legend,button,input,textarea,th,td{ margin:0; padding:0;}
|
||||
body,table,input,textarea,select,button { font-family: "微软雅黑","宋体"; font-size:12px;line-height:1.5; background:#eaebec;}
|
||||
div,img,tr,td,table{ border:0;}
|
||||
table,tr,td{border:0;}
|
||||
ol,ul,li{ list-style-type:none}
|
||||
.new_content{ background:#fff; width: 100%;}
|
||||
.email-page-link{ }
|
||||
.email-link-top{ }
|
||||
.c_white{ color:#fff;}
|
||||
.email-link-con{ }
|
||||
.email-link-line{ }
|
||||
.email-link-footer{ padding:15px; color:#333; line-height: 1.9; }
|
||||
.c_grey02{ color: #888;}
|
||||
.fb{ font-weight: normal;}
|
||||
.f14{ }
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body style="background:#fff;">
|
||||
<div class="new_content">
|
||||
<div style="width: 598px; background:#fff; margin:20px auto;">
|
||||
<div style="height:50px; width: 578px; background:#3b94d6; padding:9px 10px 6px;border:1px solid #ddd; border-bottom:none;">
|
||||
<a href="{baseurl}"><img src="{baseurl}/images/email_logo.png" height="45" ></a>
|
||||
<p style="color:#fff; float:right; margin-top:15px;">确实开源,协同创新</p>
|
||||
<div style="clear:both; overflow:hidden;"></div>
|
||||
</div>
|
||||
<div style="width: 558px; border-left:1px solid #ddd;border-right:1px solid #ddd; background:#fff; padding:20px; color:#333; line-height: 1.9;">
|
||||
<p style="font-size: 14px; color:#333;">
|
||||
{receiver},您好!<br/>
|
||||
你已被拉入组织 <a href="{baseurl}/{login}" style="font-weight:bold;color:#3b94d6;">{organization}</a> 的 <a href="{baseurl}/{login}" style="font-weight:bold;color:#3b94d6;">{team}</a> 团队,拥有{role}权限
|
||||
</p>
|
||||
<div style="width: 100%; border-top: 1px solid #ddd; margin:10px 0;"></div>
|
||||
</div>
|
||||
<div style="padding:20px; color:#333; line-height: 1.9;background: #eee;border:1px solid #ddd; border-top:none; width: 558px;">
|
||||
<p style="color:#888; float:left;">如果您在使用中有任何的疑问和建议,欢迎您给我们反馈意见<br/>
|
||||
QQ群:1071514693</p>
|
||||
<p style="color:#888; float:right;font-weight: bold;font-size: 16px;">GitLink团队</p>
|
||||
<div style="clear:both; overflow:hidden;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>被移出组织团队</title>
|
||||
<style type="text/css">
|
||||
body,h1,h2,h3,h4,h5,h6,hr,p,blockquote,dl,dt,dd,ul,ol,li,pre,form,fieldset,legend,button,input,textarea,th,td{ margin:0; padding:0;}
|
||||
body,table,input,textarea,select,button { font-family: "微软雅黑","宋体"; font-size:12px;line-height:1.5; background:#eaebec;}
|
||||
div,img,tr,td,table{ border:0;}
|
||||
table,tr,td{border:0;}
|
||||
ol,ul,li{ list-style-type:none}
|
||||
.new_content{ background:#fff; width: 100%;}
|
||||
.email-page-link{ }
|
||||
.email-link-top{ }
|
||||
.c_white{ color:#fff;}
|
||||
.email-link-con{ }
|
||||
.email-link-line{ }
|
||||
.email-link-footer{ padding:15px; color:#333; line-height: 1.9; }
|
||||
.c_grey02{ color: #888;}
|
||||
.fb{ font-weight: normal;}
|
||||
.f14{ }
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body style="background:#fff;">
|
||||
<div class="new_content">
|
||||
<div style="width: 598px; background:#fff; margin:20px auto;">
|
||||
<div style="height:50px; width: 578px; background:#3b94d6; padding:9px 10px 6px;border:1px solid #ddd; border-bottom:none;">
|
||||
<a href="{baseurl}"><img src="{baseurl}/images/email_logo.png" height="45" ></a>
|
||||
<p style="color:#fff; float:right; margin-top:15px;">确实开源,协同创新</p>
|
||||
<div style="clear:both; overflow:hidden;"></div>
|
||||
</div>
|
||||
<div style="width: 558px; border-left:1px solid #ddd;border-right:1px solid #ddd; background:#fff; padding:20px; color:#333; line-height: 1.9;">
|
||||
<p style="font-size: 14px; color:#333;">
|
||||
{receiver},您好!<br/>
|
||||
你已被移出组织 <a href="{baseurl}/{login}" style="font-weight:bold;color:#3b94d6;">{organization}</a> 的 <a href="{baseurl}/{login}" style="font-weight:bold;color:#3b94d6;">{team}</a> 团队
|
||||
</p>
|
||||
<div style="width: 100%; border-top: 1px solid #ddd; margin:10px 0;"></div>
|
||||
</div>
|
||||
<div style="padding:20px; color:#333; line-height: 1.9;background: #eee;border:1px solid #ddd; border-top:none; width: 558px;">
|
||||
<p style="color:#888; float:left;">如果您在使用中有任何的疑问和建议,欢迎您给我们反馈意见<br/>
|
||||
QQ群:1071514693</p>
|
||||
<p style="color:#888; float:right;font-weight: bold;font-size: 16px;">GitLink团队</p>
|
||||
<div style="clear:both; overflow:hidden;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Reference in New Issue