Compare commits
331 Commits
master
...
standalone
| Author | SHA1 | Date |
|---|---|---|
|
|
65844ab733 | |
|
|
e49201911f | |
|
|
56082ee35e | |
|
|
6e6774ffcb | |
|
|
5c991c14be | |
|
|
cff70fa6a1 | |
|
|
76b4c79d2d | |
|
|
4f60b4c777 | |
|
|
20cb2c8eb8 | |
|
|
7b8107b95e | |
|
|
dd2d5547e3 | |
|
|
ab86b953ce | |
|
|
65f8248373 | |
|
|
32ebc94402 | |
|
|
e2bf2e0854 | |
|
|
8c32e0067e | |
|
|
7848e092e4 | |
|
|
94d5a2d531 | |
|
|
11490ecda1 | |
|
|
1cb2b821cf | |
|
|
619b6b654c | |
|
|
faff21a677 | |
|
|
11bceeada0 | |
|
|
46c6fcb94f | |
|
|
3ae18f234c | |
|
|
591804f4f3 | |
|
|
0a4381de0a | |
|
|
97612480a6 | |
|
|
d4ee34b7f8 | |
|
|
bd786372fe | |
|
|
f14ba00e04 | |
|
|
8348708c49 | |
|
|
e1e3c46aab | |
|
|
84670faae6 | |
|
|
f0247a80f8 | |
|
|
18f933d7f6 | |
|
|
62b970661b | |
|
|
d460b4924a | |
|
|
64deebf717 | |
|
|
286afb2ee0 | |
|
|
86f1dad815 | |
|
|
914136ad58 | |
|
|
5224acbca2 | |
|
|
1749a90202 | |
|
|
10d358749f | |
|
|
f502aa081e | |
|
|
552b3c2f39 | |
|
|
bb9d8eb9f3 | |
|
|
1e7e0766fa | |
|
|
5021391d90 | |
|
|
979d1c6722 | |
|
|
a92fd3a31a | |
|
|
21d0f09bc2 | |
|
|
fed9dac6cd | |
|
|
630682d49a | |
|
|
2c7d76b682 | |
|
|
20ba9d9ac7 | |
|
|
68cb51e068 | |
|
|
4f59fb7e2f | |
|
|
cdc03e5e6d | |
|
|
830dfc80eb | |
|
|
5c1d190be0 | |
|
|
fcae803640 | |
|
|
e323c3e9f1 | |
|
|
5e3319fa59 | |
|
|
2ac8e47211 | |
|
|
cf9d22b13d | |
|
|
f956bfda2a | |
|
|
2f79aab571 | |
|
|
6f7aad06c6 | |
|
|
6584b69dc1 | |
|
|
f625429cc1 | |
|
|
13e02594f7 | |
|
|
3ae73ebf06 | |
|
|
17bd3034bb | |
|
|
328f3a0b72 | |
|
|
1f41779e9b | |
|
|
4fe2dc6b28 | |
|
|
cc05584245 | |
|
|
a73c3bb44a | |
|
|
89eb4c2393 | |
|
|
d7008003c9 | |
|
|
63a5b83e96 | |
|
|
bbb06d2c08 | |
|
|
f77b2ae182 | |
|
|
bf4ff93ed9 | |
|
|
c8b80c04d6 | |
|
|
6c56712573 | |
|
|
aab613ebce | |
|
|
7759ea558c | |
|
|
f615487380 | |
|
|
47832df856 | |
|
|
a8ec291050 | |
|
|
0ea1a843da | |
|
|
4341f19c21 | |
|
|
d5ef64c31d | |
|
|
6f90c5ff88 | |
|
|
3be4408661 | |
|
|
8dd213d408 | |
|
|
dfd7e40b6a | |
|
|
81b34f941d | |
|
|
21a9162dba | |
|
|
b1e59da99c | |
|
|
2e496a17c0 | |
|
|
26fb01cfd8 | |
|
|
6db7fada1d | |
|
|
09add4f080 | |
|
|
a8140cf0a6 | |
|
|
006054f424 | |
|
|
4248c43023 | |
|
|
4a4fe2f223 | |
|
|
e6a4b09757 | |
|
|
ea12dab204 | |
|
|
4ffc9246ac | |
|
|
74825b224e | |
|
|
153afa0c77 | |
|
|
b96d32505c | |
|
|
20cd41b5e9 | |
|
|
370746c79d | |
|
|
0eda08219c | |
|
|
ef8226caf5 | |
|
|
4f6f4d781f | |
|
|
561cc46dc8 | |
|
|
c5d0a23345 | |
|
|
720aaab53a | |
|
|
a74599cbed | |
|
|
e21197921e | |
|
|
46ebf2ad7e | |
|
|
68d4c76774 | |
|
|
306310a718 | |
|
|
9429f05f39 | |
|
|
a701e17563 | |
|
|
3805feb5be | |
|
|
95899adfc4 | |
|
|
f754b3835c | |
|
|
491a73cec5 | |
|
|
fc6172935c | |
|
|
81d4b35b3c | |
|
|
69e4c49ed5 | |
|
|
8654bf5854 | |
|
|
064354e508 | |
|
|
edbaf2829d | |
|
|
be8fd9e37e | |
|
|
6e6b46976e | |
|
|
c12023c164 | |
|
|
f8eb2d87f5 | |
|
|
346c15bae3 | |
|
|
8212e2fb3d | |
|
|
67ebbabfff | |
|
|
8ff4093738 | |
|
|
fed3865fb2 | |
|
|
53307632ae | |
|
|
5ff91b0510 | |
|
|
87da55c825 | |
|
|
83a7292939 | |
|
|
9ea1f1627a | |
|
|
81ce0ca2b4 | |
|
|
dc8794151b | |
|
|
0431a42519 | |
|
|
8889beb968 | |
|
|
c56a25cdf4 | |
|
|
ede4e2ab9c | |
|
|
d0ef36e273 | |
|
|
e3dd23da3f | |
|
|
0d1ed72a18 | |
|
|
217fa5cc67 | |
|
|
4aab0ddf51 | |
|
|
907ee60c1d | |
|
|
114cb49c13 | |
|
|
89e13ecfcc | |
|
|
96cde9f76a | |
|
|
3357e56a84 | |
|
|
d316669b7f | |
|
|
bdd9518a4c | |
|
|
a3b98ea9ce | |
|
|
5cd1733a82 | |
|
|
2bd58d2ad7 | |
|
|
354b8ee8a9 | |
|
|
f044ad705d | |
|
|
4e48bdb34f | |
|
|
2905da7b14 | |
|
|
8111c13417 | |
|
|
3a38cb675c | |
|
|
c9b3500fcf | |
|
|
d5cf6e444d | |
|
|
29cde8621c | |
|
|
0d99ccce80 | |
|
|
f545615567 | |
|
|
365345f15a | |
|
|
ae6540549c | |
|
|
02e836d730 | |
|
|
22dedcc5ff | |
|
|
69f1b3862a | |
|
|
50655495a0 | |
|
|
9c26319b17 | |
|
|
2971e75cbf | |
|
|
65bab3d9e2 | |
|
|
11b2ca48cf | |
|
|
5dfc0e74a8 | |
|
|
e89a93e8ca | |
|
|
9942974c42 | |
|
|
76b70fea14 | |
|
|
e82ec9d676 | |
|
|
faa3f282a4 | |
|
|
6d65d1163a | |
|
|
e2ff617715 | |
|
|
5a0b1858c8 | |
|
|
6a8ef3ac3b | |
|
|
754ed99959 | |
|
|
a85534b394 | |
|
|
95f49450b0 | |
|
|
bcf0b376a9 | |
|
|
81a5adb21a | |
|
|
b6de7fa96b | |
|
|
01ef87f5a3 | |
|
|
a35537694c | |
|
|
2229c732ca | |
|
|
532b924ff1 | |
|
|
16a71a383b | |
|
|
7d67defa24 | |
|
|
41515575f1 | |
|
|
f4248ec14b | |
|
|
9544a5b22d | |
|
|
9cf4cc290c | |
|
|
e37d76d972 | |
|
|
c18d1d2ce4 | |
|
|
40576e321f | |
|
|
f9e7b92386 | |
|
|
40955f5a99 | |
|
|
cece63286e | |
|
|
debefe2e7c | |
|
|
ad2f42bed6 | |
|
|
473b9e3dfd | |
|
|
655bb7bb4e | |
|
|
da48040d2c | |
|
|
732a3a1405 | |
|
|
31e4d73e2a | |
|
|
bd3dd5df4a | |
|
|
85b55619c6 | |
|
|
9d968ac5db | |
|
|
a90bed0b8f | |
|
|
4151b3564f | |
|
|
bff04758b8 | |
|
|
7f386622a3 | |
|
|
9d8600eb1c | |
|
|
981dde45ef | |
|
|
b02cf8fe79 | |
|
|
44c8d0be7c | |
|
|
4afce7809d | |
|
|
10c05896fc | |
|
|
d260fcfe35 | |
|
|
d286502224 | |
|
|
cabc9775bc | |
|
|
8c9f6d6175 | |
|
|
0ae4f8decd | |
|
|
a86372dc16 | |
|
|
3eebf61f03 | |
|
|
cf6dc3a9b4 | |
|
|
2a0ce2972a | |
|
|
8cab37587e | |
|
|
542fe0b60c | |
|
|
bb720d20c1 | |
|
|
6bcdc20500 | |
|
|
5faf040862 | |
|
|
991a421b67 | |
|
|
74f928bab2 | |
|
|
9cb7a22e52 | |
|
|
6a7174781c | |
|
|
880f547b3b | |
|
|
f97ad21af5 | |
|
|
5230064b29 | |
|
|
8fffa5530c | |
|
|
02df11cc64 | |
|
|
ba2a76de8c | |
|
|
f1bf41c7f6 | |
|
|
1a282dc925 | |
|
|
829e6bfe02 | |
|
|
c3754f65cd | |
|
|
16a64027f1 | |
|
|
e6eea663a9 | |
|
|
52b46f4b89 | |
|
|
e7795faa22 | |
|
|
831576d4aa | |
|
|
2b9e53565a | |
|
|
76d3c29c42 | |
|
|
346b815e0a | |
|
|
7496a4bdd6 | |
|
|
470064ecd5 | |
|
|
974213ff59 | |
|
|
b52aa0633e | |
|
|
76545cf72f | |
|
|
14350f6812 | |
|
|
0bc702b957 | |
|
|
d5b0fccf03 | |
|
|
2ff38ad402 | |
|
|
63593535a7 | |
|
|
f767d95730 | |
|
|
e317fafb89 | |
|
|
27d73f0c11 | |
|
|
a8f06eb022 | |
|
|
6598eb6b76 | |
|
|
c97188aff8 | |
|
|
7d466217c7 | |
|
|
d86d7f5d3e | |
|
|
a2ab42f392 | |
|
|
a3517e651f | |
|
|
3e859e4469 | |
|
|
74706ab7a2 | |
|
|
8fa20c7f6b | |
|
|
f96bcfa162 | |
|
|
145463f967 | |
|
|
6a6698bc74 | |
|
|
41cbeae2f7 | |
|
|
9645f38e31 | |
|
|
fa26098426 | |
|
|
6c937e6af6 | |
|
|
ef06a808a9 | |
|
|
6d51061f49 | |
|
|
4eaf5aada2 | |
|
|
fb461b2fe6 | |
|
|
045d324809 | |
|
|
e03e011f18 | |
|
|
055e916d08 | |
|
|
37e28fdf2e | |
|
|
1a755048bb | |
|
|
fcabd83a9d | |
|
|
387f33b2b0 | |
|
|
c0e6720cd4 | |
|
|
737b6bc18f | |
|
|
616e99cc86 | |
|
|
ee47f29264 |
|
|
@ -134,11 +134,11 @@ $(document).on('turbolinks:load', function() {
|
|||
rules: {
|
||||
"user[password]": {
|
||||
required: false,
|
||||
minlength: 5
|
||||
minlength: 8
|
||||
},
|
||||
"user[password_confirmation]": {
|
||||
required: false,
|
||||
minlength: 5,
|
||||
minlength: 8,
|
||||
equalTo: "#user_password"
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -292,6 +292,7 @@ class AccountsController < ApplicationController
|
|||
UserAction.create(:action_id => user.try(:id), :action_type => "Login", :user_id => user.try(:id), :ip => request.remote_ip)
|
||||
user.update_column(:last_login_on, Time.now)
|
||||
session[:"#{default_yun_session}"] = user.id
|
||||
UserOnline.login(user.id)
|
||||
Rails.logger.info("#########_____session_default_yun_session__________###############{default_yun_session}")
|
||||
# 注册完成后有一天的试用申请(先去掉)
|
||||
# UserDayCertification.create(user_id: user.id, status: 1)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
class Action::NodeInputsController < ApplicationController
|
||||
before_action :require_admin, except: [:index]
|
||||
before_action :require_login, except: [:index]
|
||||
before_action :find_action_node
|
||||
|
||||
def index
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
class Action::NodeSelectsController < ApplicationController
|
||||
|
||||
before_action :require_admin, except: [:index]
|
||||
before_action :require_loginrequire_login, except: [:index]
|
||||
before_action :find_action_node
|
||||
|
||||
def index
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
class Action::NodeTypesController < ApplicationController
|
||||
before_action :require_admin, except: [:index]
|
||||
before_action :require_login, except: [:index]
|
||||
before_action :find_node_type, except: [:index, :create, :new]
|
||||
|
||||
def index
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
class Action::TemplatesController < ApplicationController
|
||||
before_action :require_admin, except: [:index]
|
||||
before_action :require_login, except: [:index]
|
||||
before_action :find_action_template, except: [:index, :create, :new]
|
||||
|
||||
def index
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
class Admins::DashboardsController < Admins::BaseController
|
||||
before_action :require_business
|
||||
|
||||
def index
|
||||
# 用户活跃数
|
||||
day_user_ids = CommitLog.where(created_at: today).pluck(:user_id).uniq
|
||||
|
|
@ -65,17 +67,16 @@ class Admins::DashboardsController < Admins::BaseController
|
|||
CommitLog.count
|
||||
end
|
||||
|
||||
@subject_name = ["用户数", "项目数", "组织数", "Issue数", "Issue评论数", "PR数", "Commit数"]
|
||||
@subject_icon = ["fa-user","fa-git", "fa-sitemap", "fa-warning", "fa-comments", "fa-share-alt", "fa-upload"]
|
||||
@subject_data = [@user_count, @project_count, @organization_count, @issue_count, @comment_count, @pr_count, @commit_count]
|
||||
@subject_name = ["用户数", "项目数", "组织数", "Issue数", "Issue评论数", "PR数", "Commit数", "在线用户数"]
|
||||
@subject_icon = ["fa-user","fa-git", "fa-sitemap", "fa-warning", "fa-comments", "fa-share-alt", "fa-upload", "fa-user"]
|
||||
@subject_data = [@user_count, @project_count, @organization_count, @issue_count, @comment_count, @pr_count, @commit_count, UserOnline.count]
|
||||
|
||||
if EduSetting.get("open_baidu_tongji").to_s == "true"
|
||||
tongji_service = Baidu::TongjiService.new
|
||||
@access_token = tongji_service.access_token
|
||||
Rails.logger.info "baidu_tongji_auth access_token ===== #{@access_token}"
|
||||
# @overview_data = tongji_service.api_overview
|
||||
last_date = DailyPlatformStatistic.order(:date).last || Time.now
|
||||
start_date = last_date.date
|
||||
start_date = DailyPlatformStatistic.order(:date).last.try(:date) || Time.now.to_date
|
||||
end_date = Time.now
|
||||
if @access_token.present?
|
||||
@overview_data = Rails.cache.fetch("dashboardscontroller:baidu_tongji:overview_data", expires_in: 10.minutes) do
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ class Admins::LaboratorySettingsController < Admins::BaseController
|
|||
|
||||
def form_params
|
||||
params.permit(:identifier, :name,
|
||||
:nav_logo, :login_logo, :tab_logo, :oj_banner,
|
||||
:nav_logo, :login_logo, :tab_logo, :pm_logo, :oj_banner,
|
||||
:subject_banner, :course_banner, :competition_banner, :moop_cases_banner,
|
||||
:footer, navbar: %i[name link hidden index])
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
class Admins::OrganizationsController < Admins::BaseController
|
||||
before_action :require_admin
|
||||
before_action :require_business
|
||||
before_action :finder_org, except: [:index]
|
||||
|
||||
def index
|
||||
|
|
@ -30,9 +30,11 @@ class Admins::OrganizationsController < Admins::BaseController
|
|||
end
|
||||
|
||||
def destroy
|
||||
data_bank = @org.attributes.to_json
|
||||
@org.destroy!
|
||||
Admins::DeleteOrganizationService.call(@org.login)
|
||||
UserAction.create(action_id: @org.id, action_type: "DestroyOrganization", user_id: current_user.id, :ip => request.remote_ip, data_bank: @org.attributes.to_json)
|
||||
data_bank = @org.attributes.to_json
|
||||
UserAction.create(action_id: @org.id, action_type: "DestroyOrganization", user_id: current_user.id, :ip => request.remote_ip, data_bank: data_bank)
|
||||
render_delete_success
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
class Admins::ProjectCategoriesController < Admins::BaseController
|
||||
before_action :require_admin
|
||||
before_action :require_business
|
||||
before_action :get_category, only: [:edit,:update, :destroy]
|
||||
before_action :validate_names, only: [:create, :update]
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
class Admins::ProjectIgnoresController < Admins::BaseController
|
||||
before_action :require_admin
|
||||
before_action :require_business
|
||||
before_action :set_ignore, only: [:edit,:update, :destroy,:show]
|
||||
# before_action :validate_params, only: [:create, :update]
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
class Admins::ProjectLanguagesController < Admins::BaseController
|
||||
before_action :require_admin
|
||||
before_action :require_business
|
||||
before_action :get_language, only: [:edit,:update, :destroy]
|
||||
before_action :validate_names, only: [:create, :update]
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
class Admins::ProjectLicensesController < Admins::BaseController
|
||||
before_action :require_admin
|
||||
before_action :require_business
|
||||
before_action :set_license, only: [:edit,:update, :destroy,:show]
|
||||
# before_action :validate_params, only: [:create, :update]
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
class Admins::ProjectsController < Admins::BaseController
|
||||
before_action :require_admin
|
||||
before_action :require_business
|
||||
before_action :find_project, only: [:edit, :update]
|
||||
|
||||
def index
|
||||
|
|
@ -16,6 +16,8 @@ class Admins::ProjectsController < Admins::BaseController
|
|||
projects = projects.where.not(forked_from_project_id: nil)
|
||||
when 'original'
|
||||
projects = projects.where(forked_from_project_id: nil, project_type: 'common')
|
||||
when 'mirror'
|
||||
projects = projects.where(project_type: 'sync_mirror')
|
||||
end
|
||||
@projects = paginate projects.includes(:owner, :members, :issues, :versions, :attachments, :project_score)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
class Admins::UsersController < Admins::BaseController
|
||||
before_action :require_admin
|
||||
before_action :require_business
|
||||
before_action :finder_user, except: [:index]
|
||||
|
||||
def index
|
||||
|
|
|
|||
|
|
@ -18,10 +18,10 @@ class Api::Pm::DashboardsController < Api::Pm::BaseController
|
|||
return render_error('请输入正确的pm_issue_types.') if params[:pm_issue_types].blank?
|
||||
pm_project_ids = params[:pm_project_ids].split(",") rescue []
|
||||
pm_issue_types = params[:pm_issue_types].split(",") rescue []
|
||||
@all_issues = Issue.where(pm_project_id: pm_project_ids, pm_issue_type: pm_issue_types)
|
||||
@all_issues = Issue.where(pm_project_id: pm_project_ids, pm_issue_type: pm_issue_types).order(created_on: :desc)
|
||||
@issues = @all_issues.joins(:issue_participants).where(issue_participants: {participant_id: current_user.id, participant_type: 'assigned'})
|
||||
@issues = @issues.where.not(status_id: 5) if params[:category] == "opened"
|
||||
|
||||
@issues = @issues.where("issues.id > 0")
|
||||
@issues = kaminari_paginate(@issues.distinct.pm_includes)
|
||||
@my_assign_requirements_count = @all_issues.where(pm_issue_type: 1).joins(:issue_participants).where(issue_participants: {participant_id: current_user.id, participant_type: 'assigned'}).size
|
||||
@my_assign_tasks_count = @all_issues.where(pm_issue_type: 2).joins(:issue_participants).where(issue_participants: {participant_id: current_user.id, participant_type: 'assigned'}).size
|
||||
|
|
|
|||
|
|
@ -177,7 +177,7 @@ class Api::Pm::IssuesController < Api::Pm::BaseController
|
|||
issue.fake_id = row[0]
|
||||
issue.subject = row[1]
|
||||
issue.description = row[2]
|
||||
author = User.find_by(login: row[3])
|
||||
author = User.find_by(login: row[3]) || User.where(admin: true).first
|
||||
issue.user = author
|
||||
issue.created_on = row[4]
|
||||
changer = User.find_by(login: row[5])
|
||||
|
|
|
|||
|
|
@ -8,9 +8,15 @@ class Api::Pm::PipelinesController < Api::Pm::BaseController
|
|||
tip_exception('没有查看组织的权限')
|
||||
end
|
||||
@project_ids = @owner.projects.ids
|
||||
project_gpids = @owner.projects.pluck(:gpid)
|
||||
if params[:project_ids].present?
|
||||
@project_ids = params[:project_ids].split(",")
|
||||
end
|
||||
projects = Project.where(id: @project_ids)
|
||||
projects = projects.where(is_public: ActiveModel::Type::Boolean.new.cast(params[:is_public])) if params[:is_public].present?
|
||||
project_gpids = projects.pluck(:gpid)
|
||||
@project_ids = projects.ids
|
||||
action_runs = Gitea::ActionRun.where(owner_id: @owner.gitea_uid)
|
||||
group_data = action_runs.where(status: [1,2]).group(:workflow_id, :status).count
|
||||
group_data = action_runs.where(status: [1,2]).group(:workflow_id, :status, :repo_id).count
|
||||
pipelines = Action::Pipeline.where(project_id: @project_ids).order(updated_at: :desc)
|
||||
run_files = Gitea::ActionRun.select(:workflow_id, :repo_id).where(owner_id: @owner.gitea_uid).group(:workflow_id, :repo_id)
|
||||
db_files = pipelines.pluck(:file_name)
|
||||
|
|
@ -19,21 +25,24 @@ class Api::Pm::PipelinesController < Api::Pm::BaseController
|
|||
file = file_info.workflow_id
|
||||
project = Project.find_by(gpid: file_info.repo_id)
|
||||
next if project.blank?
|
||||
unless db_files.include?(".gitea/workflows/#{file}")
|
||||
pipeline = Action::Pipeline.find_or_initialize_by(pipeline_name: file.to_s.gsub(".yml", "").gsub(".yaml", ""),
|
||||
file_name: ".gitea/workflows/#{file}",
|
||||
branch: project.default_branch,
|
||||
is_graphic_design: false,
|
||||
disable: false,
|
||||
project_id: project.id)
|
||||
interactor = Repositories::EntriesInteractor.call(@owner, project.identifier, ".gitea/workflows/#{file}", ref: project.default_branch)
|
||||
if interactor.success?
|
||||
pipeline.yaml = decode64_content(interactor.result, @owner, project.repository, project.default_branch, nil)
|
||||
if params[:generate_actions].present?
|
||||
unless db_files.include?(".gitea/workflows/#{file}")
|
||||
pipeline = Action::Pipeline.find_or_initialize_by(pipeline_name: file.to_s.gsub(".yml", "").gsub(".yaml", ""),
|
||||
file_name: ".gitea/workflows/#{file}",
|
||||
branch: project.default_branch,
|
||||
disable: false,
|
||||
project_id: project.id)
|
||||
interactor = Repositories::EntriesInteractor.call(@owner, project.identifier, ".gitea/workflows/#{file}", ref: project.default_branch)
|
||||
if interactor.success?
|
||||
pipeline.yaml = decode64_content(interactor.result, @owner, project.repository, project.default_branch, nil)
|
||||
file = interactor.result
|
||||
pipeline.sha = file['content']['sha']
|
||||
end
|
||||
pipeline.user_id = current_user.id
|
||||
pipeline.save
|
||||
# 导入的流水线统一先禁用
|
||||
# $gitea_hat_client.post_repos_actions_disable(project&.owner&.login, project&.identifier, {query: {workflow: file}}) rescue nil
|
||||
end
|
||||
pipeline.user_id = current_user.id
|
||||
pipeline.save
|
||||
# 导入的流水线统一先禁用
|
||||
$gitea_hat_client.post_repos_actions_disable(project&.owner&.login, project&.identifier, {query: {workflow: file}}) rescue nil
|
||||
end
|
||||
last_action_run = action_runs.where(repo_id: project.gpid).where(workflow_id: file).order(updated: :desc).first
|
||||
last_action_run_json = last_action_run.present? ? {
|
||||
|
|
@ -42,9 +51,9 @@ class Api::Pm::PipelinesController < Api::Pm::BaseController
|
|||
title: last_action_run.title,
|
||||
index: last_action_run.index,
|
||||
status: last_action_run.status,
|
||||
started: last_action_run.started,
|
||||
stopped: last_action_run.stopped,
|
||||
length: last_action_run.stopped-last_action_run.started,
|
||||
started: last_action_run.started.zero? ? Time.now.to_i : last_action_run.started,
|
||||
stopped: last_action_run.stopped.zero? ? Time.now.to_i : last_action_run.stopped,
|
||||
length: last_action_run.stopped.zero? ? 0 : last_action_run.stopped-last_action_run.started,
|
||||
created: last_action_run.created,
|
||||
updated: last_action_run.updated,
|
||||
} : {}
|
||||
|
|
@ -53,12 +62,12 @@ class Api::Pm::PipelinesController < Api::Pm::BaseController
|
|||
success = 0
|
||||
failure = 0
|
||||
group_data.each do |k,v|
|
||||
total += v if k[0] == file
|
||||
success += v if k[0] == file && k[1] == 1
|
||||
failure += v if k[0] == file && k[1] == 2
|
||||
total += v if k[0] == file && k[2] == file_info.repo_id
|
||||
success += v if k[0] == file && k[1] == 1 && k[2] == file_info.repo_id
|
||||
failure += v if k[0] == file && k[1] == 2 && k[2] == file_info.repo_id
|
||||
end
|
||||
@run_result << {
|
||||
repo_id: last_action_run.repo_id,
|
||||
repo_id: last_action_run&.repo_id,
|
||||
filename: ".gitea/workflows/#{file}",
|
||||
total: total,
|
||||
success: success,
|
||||
|
|
@ -67,8 +76,8 @@ class Api::Pm::PipelinesController < Api::Pm::BaseController
|
|||
end
|
||||
# Rails.logger.info("@run_result======#{@run_result}")
|
||||
@disabled_workflows = Gitea::RepoUnit.where(repo_id: project_gpids, type: 10).where("config is not null")
|
||||
@pipelines = Action::Pipeline.select("distinct project_id,max(updated_at) as updated_at")
|
||||
.where(project_id: @project_ids).group(:project_id).order("updated_at desc")
|
||||
@pipelines = Action::Pipeline.select("distinct project_id,max(updated_at) as updated_at, max(created_at) as created_at")
|
||||
.where(project_id: @project_ids).group(:project_id).order("created_at desc")
|
||||
@pipelines = @pipelines.where("pipeline_name like ?", "%#{params[:pipeline_name]}%") if params[:pipeline_name].present?
|
||||
@pipelines = @pipelines.where(pipeline_type: params[:pipeline_type]) if params[:pipeline_type].present?
|
||||
@pipelines = kaminari_paginate(@pipelines)
|
||||
|
|
|
|||
|
|
@ -5,16 +5,18 @@ class Api::Pm::WeeklyIssuesController < Api::Pm::BaseController
|
|||
return render_error('请输入正确的用户ID.') if params[:user_id].blank?
|
||||
@all_issues = Issue.joins(:issue_participants).where(issue_participants: {participant_id: params[:user_id], participant_type: ['assigned']})
|
||||
@all_issues = @all_issues.where(enterprise_identifier: @enterprise_identifier, pm_issue_type: [1,2,3])
|
||||
@this_week_all_issues = @all_issues.where("due_date >= ? and start_date <= ?", Date.today.beginning_of_week.to_s, Date.today.end_of_week.to_s).distinct
|
||||
@this_week_all_issues = @this_week_all_issues.order('created_on desc')
|
||||
@next_week_all_issues = @all_issues.where("due_date >= ? and start_date <=?", (Date.today.beginning_of_week+1.week).to_s, (Date.today.end_of_week+1.week).to_s).distinct
|
||||
@next_week_all_issues = @next_week_all_issues.order('created_on desc')
|
||||
@weekly_begin_date = params[:weekly_begin_date].to_time || Date.today.beginning_of_week rescue Date.today.beginning_of_week
|
||||
@weekly_end_date = params[:weekly_end_date].to_time || Date.today.end_of_week rescue Date.today.end_of_week
|
||||
@this_week_all_issues = @all_issues.where("due_date >= ? and start_date <= ?", @weekly_begin_date.to_s, @weekly_end_date.to_s).distinct
|
||||
@this_week_all_issues = @this_week_all_issues.order('created_on desc').pm_includes
|
||||
@next_week_all_issues = @all_issues.where("due_date >= ? and start_date <=?", (@weekly_begin_date+1.week).to_s, (@weekly_end_date+1.week).to_s).distinct
|
||||
@next_week_all_issues = @next_week_all_issues.order('created_on desc').pm_includes
|
||||
@this_week_requirement_issues = @this_week_all_issues.where(pm_issue_type: 1)
|
||||
@this_week_task_issues = @this_week_all_issues.where(pm_issue_type: 2)
|
||||
@this_week_bug_issues = @this_week_all_issues.where(pm_issue_type: 3)
|
||||
@close_requirement_issues = @this_week_requirement_issues.where(status_id: [3,5])
|
||||
@close_task_issues = @this_week_task_issues.where(status_id: [3,5])
|
||||
@close_bug_issues = @this_week_bug_issues.where(status_id: [3,5])
|
||||
@close_requirement_issues = @this_week_requirement_issues.where(status_id: [3,5]).pm_includes
|
||||
@close_task_issues = @this_week_task_issues.where(status_id: [3,5]).pm_includes
|
||||
@close_bug_issues = @this_week_bug_issues.where(status_id: [3,5]).pm_includes
|
||||
this_week_page = params[:this_week_page] || 1
|
||||
this_week_limit = params[:this_week_limit] || 15
|
||||
@this_week_all_issues = @this_week_all_issues.page(this_week_page).per(this_week_limit)
|
||||
|
|
@ -27,7 +29,9 @@ class Api::Pm::WeeklyIssuesController < Api::Pm::BaseController
|
|||
@enterprise_identifier = params[:enterprise_identifier] || ''
|
||||
@all_issues = Issue.where(enterprise_identifier: @enterprise_identifier, pm_issue_type: [1,2,3])
|
||||
@all_issues = @all_issues.where(pm_project_id: params[:pm_project_ids].split(",")) if params[:pm_project_ids].present?
|
||||
@this_week_all_issues = @all_issues.where("due_date >= ? and start_date <= ?", Date.today.beginning_of_week.to_s, Date.today.end_of_week.to_s)
|
||||
@weekly_begin_date = params[:weekly_begin_date] || Date.today.beginning_of_week.to_s
|
||||
@weekly_end_date = params[:weekly_end_date] || Date.today.end_of_week.to_s
|
||||
@this_week_all_issues = @all_issues.where("due_date >= ? and start_date <= ?", @weekly_begin_date, @weekly_end_date)
|
||||
@this_week_all_issues_group_count = @this_week_all_issues.group(:pm_project_id).count
|
||||
data = {}
|
||||
@this_week_all_issues_group_count.keys.each do |pm_project_id|
|
||||
|
|
@ -55,22 +59,40 @@ class Api::Pm::WeeklyIssuesController < Api::Pm::BaseController
|
|||
|
||||
def group_issues
|
||||
@enterprise_identifier = params[:enterprise_identifier] || ''
|
||||
@all_issues = Issue.where(enterprise_identifier: @enterprise_identifier, pm_issue_type: [1,2,3])
|
||||
root_id = params[:root_id] || -1
|
||||
@weekly_begin_date = params[:weekly_begin_date] || Date.today.beginning_of_week.to_s
|
||||
@weekly_end_date = params[:weekly_end_date] || Date.today.end_of_week.to_s
|
||||
@all_issues = Issue.none
|
||||
if root_id.to_i == -1
|
||||
@all_issues = Issue.where(root_id: nil, enterprise_identifier: @enterprise_identifier, pm_issue_type: [1,2,3])
|
||||
elsif root_id.to_i.positive?
|
||||
@all_issues = Issue.where(root_id: root_id, enterprise_identifier: @enterprise_identifier, pm_issue_type: [1,2,3])
|
||||
else
|
||||
@all_issues = Issue.where(enterprise_identifier: @enterprise_identifier, pm_issue_type: [1,2,3])
|
||||
end
|
||||
@all_issues = @all_issues.where(pm_project_id: params[:pm_project_ids].split(",")) if params[:pm_project_ids].present?
|
||||
@all_issues = @all_issues.where(pm_issue_type: params[:pm_issue_type].to_i) if params[:pm_issue_type].present?
|
||||
@this_week_all_issues = @all_issues.where("due_date >= ? and start_date <= ?", Date.today.beginning_of_week.to_s, Date.today.end_of_week.to_s)
|
||||
@this_week_all_issues = @this_week_all_issues.order('created_on desc')
|
||||
@this_week_all_issues = @all_issues.where("due_date >= ? and start_date <= ?", @weekly_begin_date, @weekly_end_date)
|
||||
@this_week_all_issues = @this_week_all_issues.order('created_on desc').pm_includes
|
||||
@this_week_all_issues = kaminari_paginate(@this_week_all_issues)
|
||||
end
|
||||
def personal_issues
|
||||
@enterprise_identifier = params[:enterprise_identifier] || ''
|
||||
return render_error('请输入正确的用户ID.') if params[:user_id].blank?
|
||||
@all_issues = Issue.joins(:issue_participants).where(issue_participants: {participant_id: params[:user_id], participant_type: ['assigned']})
|
||||
@weekly_begin_date = params[:weekly_begin_date] || Date.today.beginning_of_week.to_s
|
||||
@weekly_end_date = params[:weekly_end_date] || Date.today.end_of_week.to_s
|
||||
root_id = params[:root_id] || -1
|
||||
@all_issues = Issue.none
|
||||
if root_id.to_i == -1
|
||||
@all_issues = Issue.joins(:issue_participants).where(root_id: nil, issue_participants: {participant_id: params[:user_id], participant_type: ['assigned']})
|
||||
else
|
||||
@all_issues = Issue.joins(:issue_participants).where(root_id: root_id, issue_participants: {participant_id: params[:user_id], participant_type: ['assigned']})
|
||||
end
|
||||
@all_issues = @all_issues.where(enterprise_identifier: @enterprise_identifier, pm_issue_type: [1,2,3])
|
||||
@this_week_all_issues = @all_issues.where("due_date >= ? and start_date <= ?", Date.today.beginning_of_week.to_s, Date.today.end_of_week.to_s).distinct
|
||||
@this_week_all_issues = @this_week_all_issues.order('created_on desc')
|
||||
@next_week_all_issues = @all_issues.where("due_date >= ? and start_date <=?", (Date.today.beginning_of_week+1.week).to_s, (Date.today.end_of_week+1.week).to_s).distinct
|
||||
@next_week_all_issues = @next_week_all_issues.order('created_on desc')
|
||||
@this_week_all_issues = @all_issues.where("due_date >= ? and start_date <= ?", @weekly_begin_date, @weekly_end_date).distinct
|
||||
@this_week_all_issues = @this_week_all_issues.order('created_on desc').pm_includes
|
||||
@next_week_all_issues = @all_issues.where("due_date >= ? and start_date <=?", (@weekly_begin_date.to_date+1.week).to_s, (@weekly_end_date.to_date+1.week).to_s).distinct
|
||||
@next_week_all_issues = @next_week_all_issues.order('created_on desc').pm_includes
|
||||
this_week_page = params[:this_week_page] || 1
|
||||
this_week_limit = params[:this_week_limit] || 15
|
||||
@this_week_all_issues = @this_week_all_issues.page(this_week_page).per(this_week_limit)
|
||||
|
|
|
|||
|
|
@ -37,6 +37,11 @@ class Api::V1::BaseController < ApplicationController
|
|||
params.fetch(:page, 1)
|
||||
end
|
||||
|
||||
def load_organization
|
||||
@organization = Organization.find_by(login: params[:owner]) || Organization.find_by(id: params[:owner])
|
||||
return render_not_found("组织不存在") if @organization.nil?
|
||||
end
|
||||
|
||||
# 具有对仓库的管理权限
|
||||
def require_manager_above
|
||||
@project = load_project
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ class Api::V1::Issues::JournalsController < Api::V1::BaseController
|
|||
end
|
||||
|
||||
def load_issue
|
||||
@issue = @project.issues.issue_issue.where(project_issues_index: params[:index]).where.not(id: params[:index]).take || @project.issues.issue_issue.find_by_id(params[:index])
|
||||
@issue = @project.issues.where(project_issues_index: params[:index]).where.not(id: params[:index]).take || @project.issues.find_by_id(params[:index])
|
||||
if @issue.blank?
|
||||
render_not_found("疑修不存在!")
|
||||
end
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ class Api::V1::IssuesController < Api::V1::BaseController
|
|||
|
||||
def index
|
||||
IssueTag.init_data(@project.id) unless $redis_cache.hget("project_init_issue_tags", @project.id)
|
||||
ProjectTemplates::Issue.init_data(@project.id)
|
||||
@object_result = Api::V1::Issues::ListService.call(@project, query_params, current_user)
|
||||
@total_issues_count = @object_result[:total_issues_count]
|
||||
@opened_issues_count = @object_result[:opened_issues_count]
|
||||
|
|
|
|||
|
|
@ -0,0 +1,46 @@
|
|||
class Api::V1::Organizations::ProjectsController < Api::V1::BaseController
|
||||
before_action :load_organization
|
||||
|
||||
def index
|
||||
public_projects_sql = @organization.projects.where(is_public: true).to_sql
|
||||
private_projects_sql = @organization.projects
|
||||
.where(is_public: false)
|
||||
.joins(team_projects: {team: :team_users})
|
||||
.where(team_users: {user_id: current_user.id}).to_sql
|
||||
@projects = Project.from("( #{ public_projects_sql} UNION #{ private_projects_sql } ) AS projects")
|
||||
# 表情处理
|
||||
keywords = params[:search].to_s.each_char.select { |c| c.bytes.first < 240 }.join('')
|
||||
@projects = @projects.where(is_public: params[:is_public]) if params[:is_public].present?
|
||||
@projects = @projects.where(id: params[:pm_project_repository_ids].split(',')) if params[:pm_project_repository_ids].present?
|
||||
@projects = @projects.where.not(id: params[:exclude_ids].to_s.split(",")) if params[:exclude_ids].present?
|
||||
@projects = @projects.where(project_type: ['mirror', 'common']).where("gpid is not null") if params[:actived].present?
|
||||
@projects = @projects.ransack(name_or_identifier_cont: keywords).result if params[:search].present?
|
||||
@projects = @projects.includes(:owner).order("projects.#{sort} #{sort_direction}")
|
||||
@projects = kaminari_paginate(@projects)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_organization
|
||||
@organization = Organization.find_by(login: params[:owner]) || Organization.find_by(id: params[:owner])
|
||||
return render_not_found("组织不存在") if @organization.nil?
|
||||
return render_forbidden("没有查看组织的权限") if org_limited_condition || org_privacy_condition
|
||||
end
|
||||
|
||||
def org_limited_condition
|
||||
@organization.organization_extension.limited? && !current_user.logged?
|
||||
end
|
||||
|
||||
def org_privacy_condition
|
||||
return false if current_user.admin?
|
||||
@organization.organization_extension.privacy? && @organization.organization_users.where(user_id: current_user.id).blank?
|
||||
end
|
||||
|
||||
def sort
|
||||
Project.column_names.include?(params[:sort_by]) ? params[:sort_by] : 'updated_on'
|
||||
end
|
||||
|
||||
def sort_direction
|
||||
%w(desc asc).include?(params[:sort_direction]) ? params[:sort_direction] : 'desc'
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
class Api::V1::Organizations::SyncRepositoriesController < Api::V1::BaseController
|
||||
before_action :load_organization, only: [:create]
|
||||
|
||||
def create
|
||||
return render_error("请输入正确的外部组织login") unless params[:external_login].present?
|
||||
# 拉取外部组织仓库列表
|
||||
url = URI("https://api.github.com/orgs/#{params[:external_login]}/repos?page=#{params[:page]}&per_page=#{params[:limit]}")
|
||||
https = Net::HTTP.new(url.host, url.port)
|
||||
https.use_ssl = true
|
||||
request = Net::HTTP::Get.new(url)
|
||||
request["Authorization"] = "Bearer #{params[:external_token]}"
|
||||
response = https.request(request)
|
||||
if response.code == "200"
|
||||
repos = JSON.parse(response.body)
|
||||
repos.each do |repo|
|
||||
# 检查是否已经存在该仓库
|
||||
@project = @organization.projects.find_by(identifier: repo["name"])
|
||||
if @project.present?
|
||||
if @project.repository.mirror.failed?
|
||||
@project.destroy!
|
||||
mirror_params = {name: repo["name"], user_id: @organization.id, description: repo["description"], repository_name: repo["name"], auth_token: params[:external_token], clone_addr: repo["clone_url"]}
|
||||
@project = ::Projects::MigrateService.call(current_user, mirror_params)
|
||||
end
|
||||
@project.update_column(:created_on, repo['created_at'].to_time)
|
||||
@project.update_column(:updated_on, repo['updated_at'].to_time)
|
||||
next
|
||||
else
|
||||
mirror_params = {name: repo["name"], user_id: @organization.id, description: repo["description"], repository_name: repo["name"], auth_token: params[:external_token], clone_addr: repo["clone_url"]}
|
||||
@project = ::Projects::MigrateService.call(current_user, mirror_params)
|
||||
@project.update_column(:created_on, repo['created_at'].to_time)
|
||||
@project.update_column(:updated_on, repo['updated_at'].to_time)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def sync_repository_params
|
||||
params.permit(:external_token)
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -2,7 +2,7 @@ class Api::V1::ProjectTopicsController < Api::V1::BaseController
|
|||
|
||||
def index
|
||||
@project_topics = ProjectTopic
|
||||
@project_topics = @project_topics.ransack(name_cont: params[:keyword]) if params[:keyword].present?
|
||||
@project_topics = @project_topics.ransack(name_cont: params[:keyword]).result if params[:keyword].present?
|
||||
# @project_topics = @project_topics.includes(:projects)
|
||||
@project_topics = kaminary_select_paginate(@project_topics)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
class Api::V1::Projects::Actions::RunsController < Api::V1::Projects::Actions::BaseController
|
||||
|
||||
def index
|
||||
@files = $gitea_client.get_repos_contents_by_owner_repo_filepath(@project&.owner&.login, @project&.identifier, ".gitea/workflows") rescue []
|
||||
@files = $gitea_client.get_repos_contents_by_owner_repo_filepath(@project&.owner&.login, @project&.identifier, ".gitea/workflows", {query: {ref: params[:ref]}}) rescue []
|
||||
@has_file = @files.select { |i| i['name'] == params[:workflow] }.present?
|
||||
if @has_file
|
||||
@result_object = Api::V1::Projects::Actions::Runs::ListService.call(@project, {workflow: params[:workflow], page: page, limit: limit}, current_user&.gitea_token)
|
||||
@result_object = Api::V1::Projects::Actions::Runs::ListService.call(@project, {workflow: params[:workflow], page: page, limit: limit, ref: params[:ref]}, current_user&.gitea_token)
|
||||
@begin_num = (page.to_i - 1) * limit.to_i
|
||||
end
|
||||
end
|
||||
|
|
@ -12,7 +12,7 @@ class Api::V1::Projects::Actions::RunsController < Api::V1::Projects::Actions::B
|
|||
def create
|
||||
return render_error("请输入正确的流水线文件!") if params[:workflow].blank?
|
||||
return render_error("请输入正确的分支!") if params[:ref].blank?
|
||||
gitea_result = $gitea_hat_client.post_repos_actions_runs_by_owner_repo(@project&.owner&.login, @project&.identifier, {query: {workflow: params[:workflow], ref: params[:ref]}})
|
||||
gitea_result = $gitea_hat_client.post_repos_actions_runs_by_owner_repo(@project&.owner&.login, @project&.identifier, {query: {workflow: params[:workflow], ref: params[:ref], access_token: current_user.gitea_token}})
|
||||
if gitea_result
|
||||
render_ok
|
||||
else
|
||||
|
|
@ -22,7 +22,7 @@ class Api::V1::Projects::Actions::RunsController < Api::V1::Projects::Actions::B
|
|||
|
||||
def rerun
|
||||
return render_error("请输入正确的流水线记录ID!") if params[:run_id].blank?
|
||||
gitea_result = $gitea_hat_client.post_repos_actions_runs_rerun_by_owner_repo_run(@project&.owner&.login, @project&.identifier, params[:run_id]) rescue nil
|
||||
gitea_result = $gitea_hat_client.post_repos_actions_runs_rerun_by_owner_repo_run(@project&.owner&.login, @project&.identifier, params[:run_id], {query: {access_token: current_user.gitea_token}}) rescue nil
|
||||
if gitea_result
|
||||
render_ok
|
||||
else
|
||||
|
|
@ -33,7 +33,7 @@ class Api::V1::Projects::Actions::RunsController < Api::V1::Projects::Actions::B
|
|||
def job_rerun
|
||||
return render_error("请输入正确的流水线记录ID!") if params[:run_id].blank?
|
||||
return render_error("请输入正确的流水线任务ID") if params[:job].blank?
|
||||
gitea_result = $gitea_hat_client.post_repos_actions_runs_jobs_rerun_by_owner_repo_run_job(@project&.owner&.login, @project&.identifier, params[:run_id], params[:job]) rescue nil
|
||||
gitea_result = $gitea_hat_client.post_repos_actions_runs_jobs_rerun_by_owner_repo_run_job(@project&.owner&.login, @project&.identifier, params[:run_id], params[:job], {query: {access_token: current_user.gitea_token}}) rescue nil
|
||||
if gitea_result
|
||||
render_ok
|
||||
else
|
||||
|
|
@ -58,4 +58,15 @@ class Api::V1::Projects::Actions::RunsController < Api::V1::Projects::Actions::B
|
|||
redirect_to file_path
|
||||
end
|
||||
|
||||
def cancel
|
||||
return render_error("请输入正确的流水线记录ID!") if params[:run_id].blank?
|
||||
http = Gitea::Api::Hat::Http.new($gitea_hat_client.config)
|
||||
gitea_result = http.post("/repos/#{@project&.owner&.login}/#{@project&.identifier}/actions/runs/#{params[:run_id]}/cancel") rescue nil
|
||||
if gitea_result
|
||||
render_ok
|
||||
else
|
||||
render_error("停止流水线任务失败")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -24,7 +24,25 @@ class Api::V1::Projects::BranchesController < Api::V1::BaseController
|
|||
render :json => response.read_body
|
||||
end
|
||||
|
||||
def index
|
||||
def osredm
|
||||
url = URI("https://osredm.com/api/#{params[:owner]}/#{params[:repo]}/branches?access_token=#{params[:token]}&page=#{page}&per_page=#{limit}")
|
||||
https = Net::HTTP.new(url.host, url.port)
|
||||
https.use_ssl = true
|
||||
|
||||
request = Net::HTTP::Get.new(url)
|
||||
# request["Authorization"] = "Bearer #{params[:token]}"
|
||||
response = https.request(request)
|
||||
res = JSON.parse(response.body)
|
||||
|
||||
if res[0].blank? && res['status'].to_i == 401
|
||||
render :json => { "message": "无效token" }
|
||||
return
|
||||
end
|
||||
|
||||
render :json => response.read_body
|
||||
end
|
||||
|
||||
def index
|
||||
@result_object = Api::V1::Projects::Branches::ListService.call(@project, {name: params[:keyword], state: params[:state], page: page, limit: limit}, current_user&.gitea_token)
|
||||
end
|
||||
|
||||
|
|
@ -32,15 +50,35 @@ class Api::V1::Projects::BranchesController < Api::V1::BaseController
|
|||
@result_object = Api::V1::Projects::Branches::AllListService.call(@project, current_user&.gitea_token)
|
||||
end
|
||||
|
||||
before_action :require_operate_above, only: [:create, :destroy, :restore]
|
||||
before_action :require_operate_above, only: [:create, :delete, :destroy, :restore]
|
||||
|
||||
def create
|
||||
@result_object = Api::V1::Projects::Branches::CreateService.call(@project, branch_params, current_user&.gitea_token)
|
||||
@project.update_column(:updated_on, Time.now)
|
||||
end
|
||||
|
||||
def delete
|
||||
@result_object = Api::V1::Projects::Branches::DeleteService.call(@project, params[:branch_name], current_user&.gitea_token)
|
||||
if @result_object
|
||||
@project.update_column(:updated_on, Time.now)
|
||||
# 有开启的pr需要一同关闭
|
||||
# 1、删除本仓库中存在未关闭的pr,即本仓库分支1->分支2
|
||||
# 2、如果是fork仓库,考虑删除主仓库中存在未关闭的pr,即本仓库:分支1->主:分支2,同时分两种删除:1删除本仓库分支1,2删除主仓库分支2
|
||||
close_pull_requests_by(@project, params[:branch_name])
|
||||
if @project.forked_from_project_id.present?
|
||||
# fork项目中删除分支
|
||||
close_pull_requests_by(@project.fork_project, params[:branch_name])
|
||||
end
|
||||
|
||||
return render_ok
|
||||
else
|
||||
return render_error('删除分支失败!')
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@result_object = Api::V1::Projects::Branches::DeleteService.call(@project, params[:name], current_user&.gitea_token)
|
||||
@name = params[:name].include?('.json') ? params[:name][0..-6] : params[:name]
|
||||
@result_object = Api::V1::Projects::Branches::DeleteService.call(@project, Base64.decode64(@name), current_user&.gitea_token)
|
||||
if @result_object
|
||||
@project.update_column(:updated_on, Time.now)
|
||||
# 有开启的pr需要一同关闭
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ class Api::V1::Projects::CommitsController < Api::V1::BaseController
|
|||
|
||||
def files
|
||||
if params[:filepath].present?
|
||||
@result_object = $gitea_hat_client.get_repos_commits_files_by_owner_repo_sha_filepath(@project&.owner.login, @project&.identifier, params[:sha], CGI.escape(params[:filepath]), {query: {token: current_user&.gitea_token}})
|
||||
@result_object = $gitea_hat_client.get_repos_commits_files_by_owner_repo_sha_filepath(@project&.owner.login, @project&.identifier, params[:sha], URI.escape(params[:filepath]), {query: {token: current_user&.gitea_token}})
|
||||
else
|
||||
@result_object = $gitea_hat_client.get_repos_commits_files_by_owner_repo_sha(@project&.owner.login, @project&.identifier, params[:sha], {query: {token: current_user&.gitea_token, page: page, limit: limit}})
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,31 +1,32 @@
|
|||
class Api::V1::Projects::PipelinesController < Api::V1::BaseController
|
||||
include RepositoriesHelper
|
||||
include Api::ActionValidatorHelper
|
||||
before_action :require_operate_above, except: [:upload_results, :run_results]
|
||||
|
||||
def index
|
||||
pipelines = Action::Pipeline.where(project_id: @project.id).order(updated_at: :desc)
|
||||
@files = $gitea_client.get_repos_contents_by_owner_repo_filepath(@project&.owner&.login, @project&.identifier, ".gitea/workflows") rescue []
|
||||
@action_runs = Gitea::ActionRun.where(repo_id: @project.gpid)
|
||||
group_data = @action_runs.where(status: [1,2]).group(:workflow_id, :status).count
|
||||
group_data = @action_runs.where(status: [1,2]).group(:workflow_id, :status, :repo_id).count
|
||||
db_files = pipelines.pluck(:file_name)
|
||||
@run_result = []
|
||||
@files.map { |i| i['name'] }.each do |file|
|
||||
unless db_files.include?(".gitea/workflows/#{file}")
|
||||
pipeline = Action::Pipeline.find_or_initialize_by(pipeline_name: file.to_s.gsub(".yml", "").gsub(".yaml", ""),
|
||||
file_name: ".gitea/workflows/#{file}",
|
||||
branch: @project.default_branch,
|
||||
is_graphic_design: false,
|
||||
disable: false,
|
||||
project_id: @project.id)
|
||||
interactor = Repositories::EntriesInteractor.call(@owner, @project.identifier, ".gitea/workflows/#{file}", ref: @project.default_branch)
|
||||
if interactor.success?
|
||||
pipeline.yaml = decode64_content(interactor.result, @owner, @project.repository, @project.default_branch, nil)
|
||||
end
|
||||
pipeline.user_id = current_user.id
|
||||
pipeline.save
|
||||
# 导入的流水线统一先禁用
|
||||
$gitea_hat_client.post_repos_actions_disable(@project&.owner&.login, @project&.identifier, {query: {workflow: file}}) rescue nil
|
||||
end
|
||||
# unless db_files.include?(".gitea/workflows/#{file}")
|
||||
# pipeline = Action::Pipeline.find_or_initialize_by(pipeline_name: file.to_s.gsub(".yml", "").gsub(".yaml", ""),
|
||||
# file_name: ".gitea/workflows/#{file}",
|
||||
# branch: @project.default_branch,
|
||||
# is_graphic_design: false,
|
||||
# disable: false,
|
||||
# project_id: @project.id)
|
||||
# interactor = Repositories::EntriesInteractor.call(@owner, @project.identifier, ".gitea/workflows/#{file}", ref: @project.default_branch)
|
||||
# if interactor.success?
|
||||
# pipeline.yaml = decode64_content(interactor.result, @owner, @project.repository, @project.default_branch, nil)
|
||||
# end
|
||||
# pipeline.user_id = current_user.id
|
||||
# pipeline.save
|
||||
# # 导入的流水线统一先禁用
|
||||
# $gitea_hat_client.post_repos_actions_disable(@project&.owner&.login, @project&.identifier, {query: {workflow: file}}) rescue nil
|
||||
# end
|
||||
last_action_run = @action_runs.where(workflow_id: file).order(updated: :desc).first
|
||||
last_action_run_json = last_action_run.present? ? {
|
||||
id: last_action_run.id,
|
||||
|
|
@ -44,9 +45,9 @@ class Api::V1::Projects::PipelinesController < Api::V1::BaseController
|
|||
success = 0
|
||||
failure = 0
|
||||
group_data.each do |k,v|
|
||||
total += v if k[0] == file
|
||||
success += v if k[0] == file && k[1] == 1
|
||||
failure += v if k[0] == file && k[1] == 2
|
||||
total += v if k[0] == file && k[2] == @project.gpid
|
||||
success += v if k[0] == file && k[1] == 1 && k[2] == @project.gpid
|
||||
failure += v if k[0] == file && k[1] == 2 && k[2] == @project.gpid
|
||||
end
|
||||
@run_result << {
|
||||
filename: ".gitea/workflows/#{file}",
|
||||
|
|
@ -73,42 +74,65 @@ class Api::V1::Projects::PipelinesController < Api::V1::BaseController
|
|||
end
|
||||
|
||||
def create
|
||||
@pipeline = params[:id].present? ? Action::Pipeline.find(params[:id]) : Action::Pipeline.find_or_initialize_by(pipeline_name: params[:pipeline_name], project_id: @project.id)
|
||||
branch = params[:branch] || @project.default_branch
|
||||
@pipeline = params[:id].present? ? Action::Pipeline.find(params[:id]) : Action::Pipeline.find_or_initialize_by(pipeline_name: params[:pipeline_name], project_id: @project.id, branch: branch)
|
||||
if @pipeline.pipeline_name != params[:pipeline_name]
|
||||
has_pipeline = Action::Pipeline.where(pipeline_name: params[:pipeline_name], project_id: @project.id).where.not(id: @pipeline.id)
|
||||
tip_exception("已经存在#{params[:pipeline_name]}流水线!") if has_pipeline.present?
|
||||
if @pipeline.yaml.present?
|
||||
sha = get_pipeline_file_sha(@pipeline.file_name, @pipeline.branch)
|
||||
if sha.present?
|
||||
interactor = Gitea::UpdateFileInteractor.call(current_user.gitea_token, @owner.login, content_params("update", params[:pipeline_name]).merge(sha: sha, from_path: "#{@pipeline.pipeline_name}"))
|
||||
new_file_sha = get_pipeline_file_sha(".gitea/workflows/#{params[:pipeline_name]}.yml", @pipeline.branch)
|
||||
# 重命名的新文件存在时,直接修改新文件new_file_sha, 同时删除老文件
|
||||
if sha.present? && new_file_sha.present?
|
||||
interactor = Gitea::UpdateFileInteractor.call(current_user.gitea_token, @owner.login, content_params("update", params[:pipeline_name]).merge(sha: new_file_sha, from_path: ".gitea/workflows/#{params[:pipeline_name]}.yml"))
|
||||
tip_exception(interactor.error) unless interactor.success?
|
||||
del_interactor = Gitea::DeleteFileInteractor.call(current_user.gitea_token, @owner.login, del_content_params(sha).merge(identifier: @project.identifier))
|
||||
tip_exception(del_interactor.error) unless del_interactor.success?
|
||||
elsif sha.present? && new_file_sha.blank?
|
||||
interactor = Gitea::UpdateFileInteractor.call(current_user.gitea_token, @owner.login, content_params("update", params[:pipeline_name]).merge(sha: sha, from_path: ".gitea/workflows/#{@pipeline.pipeline_name}.yml"))
|
||||
tip_exception(interactor.error) unless interactor.success?
|
||||
end
|
||||
end
|
||||
else
|
||||
has_pipeline = Action::Pipeline.where(pipeline_name: params[:pipeline_name], project_id: @project.id)
|
||||
tip_exception("已经存在#{params[:pipeline_name]}流水线!") if has_pipeline.present?
|
||||
end
|
||||
@pipeline.user_id = current_user.id
|
||||
@pipeline.pipeline_name = params[:pipeline_name]
|
||||
@pipeline.file_name = ".gitea/workflows/#{@pipeline.pipeline_name}.yml"
|
||||
@pipeline.branch = params[:branch] || @project.default_branch
|
||||
@pipeline.branch = branch
|
||||
@pipeline.is_graphic_design = params[:pipeline_type] == 2 ? true : false
|
||||
@pipeline.pipeline_type = params[:pipeline_type] if params[:pipeline_type].present?
|
||||
if params[:pipelineTemplateJson].present?
|
||||
@pipeline.json = params[:pipelineTemplateJson].to_unsafe_hash.to_json
|
||||
@pipeline.yaml = build_pipeline_yaml_new(@pipeline.pipeline_name, params[:pipelineTemplateJson])
|
||||
end
|
||||
@pipeline.save!
|
||||
end
|
||||
|
||||
def save_yaml
|
||||
@pipeline = params[:id].present? ? Action::Pipeline.find(params[:id]) : Action::Pipeline.find_or_initialize_by(pipeline_name: params[:pipeline_name], project_id: @project.id)
|
||||
branch = params[:branch] || @project.default_branch
|
||||
@pipeline = params[:id].present? ? Action::Pipeline.find(params[:id]) : Action::Pipeline.find_or_initialize_by(pipeline_name: params[:pipeline_name], project_id: @project.id, branch: branch)
|
||||
@pipeline.file_name = ".gitea/workflows/#{@pipeline.pipeline_name}.yml"
|
||||
@pipeline.branch = params[:branch] if params[:branch].present?
|
||||
@pipeline.json = params[:pipeline_json].to_json if params[:pipeline_json].present?
|
||||
@pipeline.pipeline_name = params[:pipeline_name] if params[:pipeline_name].present?
|
||||
pipeline_yaml = params[:pipeline_yaml].present? ? params[:pipeline_yaml] : build_pipeline_yaml_new(@pipeline.pipeline_name, params[:pipeline_json])
|
||||
tip_exception("流水线yaml内空不能为空") if pipeline_yaml.blank?
|
||||
# result = validate_string(pipeline_yaml, @pipeline.branch, @project.default_branch)
|
||||
# unless result[:valid]
|
||||
# tip_exception(result[:errors].join(","))
|
||||
# end
|
||||
@pipeline.yaml = pipeline_yaml
|
||||
#Rails.logger.info "pipeline_yaml base64=========================#{Base64.encode64(@pipeline.yaml).gsub(/\n/, '')}"
|
||||
sha = get_pipeline_file_sha(@pipeline.file_name, @pipeline.branch)
|
||||
#Rails.logger.info "content_params=========#{content_params("create")}"
|
||||
interactor = sha.present? ? Gitea::UpdateFileInteractor.call(current_user.gitea_token, @owner.login, content_params("update").merge(sha: sha)) : Gitea::CreateFileInteractor.call(current_user.gitea_token, @owner.login, content_params("create"))
|
||||
interactor = sha.present? ? Gitea::UpdateFileInteractor.call(current_user.gitea_token, @owner.login, content_params("update").merge(sha: sha, from_path: ".gitea/workflows/#{@pipeline.pipeline_name}.yml")) : Gitea::CreateFileInteractor.call(current_user.gitea_token, @owner.login, content_params("create"))
|
||||
tip_exception(interactor.error) unless interactor.success?
|
||||
file = interactor.result
|
||||
@pipeline.pipeline_type = @pipeline.json.present? ? 2 : 1
|
||||
@pipeline.user_id = current_user.id if @pipeline.user_id.blank?
|
||||
@pipeline.pipeline_type = params[:pipeline_json].present? ? 2 : 1
|
||||
@pipeline.sha = sha.present? ? sha : file['content']['sha']
|
||||
@pipeline.save
|
||||
render_ok({ pipeline_yaml: pipeline_yaml, pipeline_name: @pipeline.pipeline_name, file_name: @pipeline.file_name, sha: sha.present? ? sha : file['content']['sha'] })
|
||||
end
|
||||
|
|
@ -148,7 +172,7 @@ class Api::V1::Projects::PipelinesController < Api::V1::BaseController
|
|||
interactor = Gitea::DeleteFileInteractor.call(current_user.gitea_token, @owner.login, del_content_params(sha).merge(identifier: @project.identifier))
|
||||
tip_exception(interactor.error) unless interactor.success?
|
||||
end
|
||||
Gitea::ActionRun.where(repo_id: @pipeline.project.gpid).destroy_all
|
||||
Gitea::ActionRun.where(repo_id: @pipeline.project.gpid, workflow_id: "#{@pipeline.pipeline_name}.yml").destroy_all
|
||||
@pipeline.destroy!
|
||||
end
|
||||
render_ok
|
||||
|
|
@ -291,16 +315,22 @@ class Api::V1::Projects::PipelinesController < Api::V1::BaseController
|
|||
node.node_id = input_node["id"] if input_node["id"].present?
|
||||
run_values = {}
|
||||
input_values = {}
|
||||
env_input_values = {}
|
||||
if input_node["data"]["inputs"].present?
|
||||
input_node["data"]["inputs"].each do |input|
|
||||
if input["name"].to_s.gsub("--", "") == "run"
|
||||
run_values = run_values.merge({ "#{input["name"].gsub("--", "")}": "#{input["value"]}" })
|
||||
else
|
||||
input_values = input_values.merge({ "#{input["name"].gsub("--", "")}": "#{input["value"]}" })
|
||||
if input["type"] == "Action::NodeInputs::Env"
|
||||
env_input_values = env_input_values.merge({ "#{input["name"].gsub("--", "")}": "#{input["value"]}" })
|
||||
else
|
||||
input_values = input_values.merge({ "#{input["name"].gsub("--", "")}": "#{input["value"]}" })
|
||||
end
|
||||
end
|
||||
end
|
||||
node.run_values = run_values
|
||||
node.input_values = input_values
|
||||
node.env_input_values = env_input_values
|
||||
end
|
||||
node
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,55 @@
|
|||
class Api::V1::Projects::ProjectTemplatesController < Api::V1::BaseController
|
||||
before_action :require_public_and_member_above, only: [:index, :show]
|
||||
|
||||
def index
|
||||
@project_templates = ProjectTemplate.where(project_id: @project.id)
|
||||
@project_templates = @project_templates.where(type: params[:type]) if params[:type].present?
|
||||
@project_templates = @project_templates.order(created_at: :asc)
|
||||
@project_templates = kaminari_paginate(@project_templates)
|
||||
end
|
||||
|
||||
def show
|
||||
@project_template = ProjectTemplate.find_by_id(params[:id])
|
||||
if @project_template.blank?
|
||||
render_not_found("模板不存在!")
|
||||
end
|
||||
end
|
||||
|
||||
before_action :require_operate_above, only: [:create, :update, :destroy]
|
||||
|
||||
def create
|
||||
@project_template = ProjectTemplate.new(project_template_params)
|
||||
@project_template.project_id = @project.id
|
||||
if @project_template.save!
|
||||
render_ok
|
||||
else
|
||||
render_error("创建模板失败!")
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
@project_template = ProjectTemplate.find_by_id(params[:id])
|
||||
return render_not_found("模板不存在!") if @project_template.blank?
|
||||
if @project_template.update!(project_template_params)
|
||||
render_ok
|
||||
else
|
||||
render_error("更新模板失败!")
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@project_template = ProjectTemplate.find_by_id(params[:id])
|
||||
return render_not_found("模板不存在!") if @project_template.blank?
|
||||
if @project_template.destroy!
|
||||
render_ok
|
||||
else
|
||||
render_error("删除模板失败!")
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def project_template_params
|
||||
params.require(:project_template).permit(:type, :name, :content)
|
||||
end
|
||||
end
|
||||
|
|
@ -6,16 +6,38 @@ class Api::V1::Projects::Pulls::PullsController < Api::V1::BaseController
|
|||
@pulls = kaminari_paginate(@pulls)
|
||||
end
|
||||
|
||||
before_action :load_pull_request, only: [:show, :files]
|
||||
before_action :load_pull_request, only: [:show, :reopen, :files]
|
||||
|
||||
def show
|
||||
@result_object = Api::V1::Projects::Pulls::GetService.call(@project, @pull_request, current_user&.gitea_token)
|
||||
@last_review = @pull_request.reviews.order(created_at: :desc).take
|
||||
end
|
||||
|
||||
def reopen
|
||||
can_merge = @project&.pull_requests.where(head: @pull_request.head, base: @pull_request.base, status: 0, is_original: @pull_request.is_original, fork_project_id: @pull_request.fork_project_id)
|
||||
if can_merge.present?
|
||||
render json: {
|
||||
status: -1,
|
||||
redirect_url:"/#{@project.owner.login}/#{@project.identifier}/pulls/#{can_merge.first.gitea_number}",
|
||||
message: "在这些分支之间的合并请求已存在",
|
||||
}
|
||||
else
|
||||
@result_object = Api::V1::Projects::Pulls::ReopenService.call(@project, @pull_request, current_user)
|
||||
if @result_object
|
||||
# 修改状态
|
||||
journal = @pull_request.issue.journals.create!({user_id: current_user.id, operate_by: 'Issue'})
|
||||
journal.journal_details.create!({property: "attr", prop_key: "status", old_value: 0, value: 4})
|
||||
ProjectActions::PullRequestEvent.build(@project, current_user, @pull_request, "reopened")
|
||||
render_ok
|
||||
else
|
||||
render_error("合并请求重新打开失败!")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def files
|
||||
if params[:filepath].present?
|
||||
@result_object = $gitea_hat_client.get_repos_pulls_files_by_owner_repo_index_filepath(@project&.owner.login, @project&.identifier, @pull_request.gitea_number, CGI.escape(params[:filepath]), {query: {token: current_user&.gitea_token}})
|
||||
@result_object = $gitea_hat_client.get_repos_pulls_files_by_owner_repo_index_filepath(@project&.owner.login, @project&.identifier, @pull_request.gitea_number, URI.escape(params[:filepath]), {query: {token: current_user&.gitea_token}})
|
||||
else
|
||||
@result_object = $gitea_hat_client.get_repos_pulls_files_by_owner_repo_index(@project&.owner.login, @project&.identifier, @pull_request.gitea_number, {query: {isNew: "true",token: current_user&.gitea_token, page: page, limit: limit}})
|
||||
end
|
||||
|
|
|
|||
|
|
@ -7,17 +7,41 @@ class Api::V1::Projects::TagsController < Api::V1::BaseController
|
|||
end
|
||||
|
||||
def show
|
||||
@result_object = Api::V1::Projects::Tags::GetService.call(@project, params[:name], current_user&.gitea_token)
|
||||
@name = params[:name].include?('.json') ? params[:name][0..-6] : params[:name]
|
||||
@result_object = Api::V1::Projects::Tags::GetService.call(@project, Base64.decode64(@name), current_user&.gitea_token)
|
||||
end
|
||||
|
||||
before_action :require_operate_above, only: [:destroy]
|
||||
before_action :require_operate_above, only: [:create, :delete, :destroy]
|
||||
|
||||
def destroy
|
||||
@result_object = Api::V1::Projects::Tags::DeleteService.call(@project, params[:name], current_user&.gitea_token)
|
||||
def create
|
||||
@result_object = Api::V1::Projects::Tags::CreateService.call(@project, tag_params, current_user&.gitea_token)
|
||||
Rails.logger.info "create tag result: #{@result_object}"
|
||||
@project.update_column(:updated_on, Time.now)
|
||||
end
|
||||
|
||||
def delete
|
||||
@result_object = Api::V1::Projects::Tags::DeleteService.call(@project, params[:tag_name], current_user&.gitea_token)
|
||||
if @result_object
|
||||
return render_ok
|
||||
else
|
||||
return render_error('删除标签失败!')
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@name = params[:name].include?('.json') ? params[:name][0..-6] : params[:name]
|
||||
@result_object = Api::V1::Projects::Tags::DeleteService.call(@project, Base64.decode64(@name), current_user&.gitea_token)
|
||||
if @result_object
|
||||
return render_ok
|
||||
else
|
||||
return render_error('删除标签失败!')
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def tag_params
|
||||
params.require(:tag).permit(:tag_name, :target, :message)
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -41,24 +41,13 @@ class Api::V1::SonarqubesController < Api::V1::BaseController
|
|||
puts %Q{\033[33m [warning] soanrqube config or configuration.yml missing,
|
||||
please add it or execute 'cp config/configuration.yml.example config/configuration.yml' \033[0m}
|
||||
end
|
||||
|
||||
sonar_content = build_sonar_content(params[:owner], @project.id, languages_precentagable.keys)
|
||||
sonar_scanner_content = {
|
||||
filepath: '.gitea/workflows/SonarScanner.yaml',
|
||||
branch: params[:branch],
|
||||
new_branch: nil,
|
||||
content: "
|
||||
on:
|
||||
# Trigger analysis when pushing to your main branches, and when creating a pull request.
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- master
|
||||
- develop
|
||||
- 'releases/**'
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
|
||||
name: Main Workflow
|
||||
name: Sonar Scanner
|
||||
jobs:
|
||||
sonarqube:
|
||||
runs-on: ubuntu-latest
|
||||
|
|
@ -66,10 +55,22 @@ class Api::V1::SonarqubesController < Api::V1::BaseController
|
|||
- uses: #{checkout_url}
|
||||
with:
|
||||
# Disabling shallow clones is recommended for improving the relevancy of reporting
|
||||
fetch-depth: 0
|
||||
fetch-depth: 1
|
||||
single-branch: true
|
||||
- name: curl doxygen
|
||||
run: |
|
||||
curl -X GET #{doxygen_url}/generate?repo=#{@project.repository.url}
|
||||
|
||||
- name: new properties
|
||||
run: |
|
||||
cat <<EOF > sonar-project.properties
|
||||
#{sonar_content}
|
||||
EOF
|
||||
|
||||
- name: new build_tmp_folder
|
||||
run: |
|
||||
mkdir build_tmp_folder
|
||||
|
||||
- name: SonarQube Scan
|
||||
uses: #{scanner_url}
|
||||
env:
|
||||
|
|
@ -91,29 +92,7 @@ class Api::V1::SonarqubesController < Api::V1::BaseController
|
|||
sonar_scanner_content[:content] = Base64.strict_encode64(sonar_scanner_content[:content])
|
||||
Gitea::CreateFileInteractor.call(@owner.gitea_token, @owner.login, sonar_scanner_content)
|
||||
end
|
||||
|
||||
sonar_content = build_sonar_content(params[:owner], @project.id, languages_precentagable.keys)
|
||||
|
||||
sonar_project_content = {
|
||||
filepath: 'sonar-project.properties',
|
||||
branch: params[:branch],
|
||||
new_branch: nil,
|
||||
"content": sonar_content,
|
||||
"message": 'Add sonar-project.properties',
|
||||
committer: {
|
||||
email: @owner.mail,
|
||||
name: @owner.login
|
||||
},
|
||||
identifier: @project.identifier
|
||||
}
|
||||
|
||||
sonar_project_exit = Repositories::EntriesInteractor.call(@owner, @project.identifier, 'sonar-project.properties', ref: params[:branch])
|
||||
if sonar_project_exit.success?
|
||||
Gitea::UpdateFileInteractor.call(@owner.gitea_token, @owner.login, sonar_project_content.merge(sha:sonar_project_exit.result['sha']))
|
||||
else
|
||||
sonar_project_content[:content] = Base64.strict_encode64(sonar_project_content[:content])
|
||||
Gitea::CreateFileInteractor.call(@owner.gitea_token, @owner.login, sonar_project_content)
|
||||
end
|
||||
$gitea_hat_client.post_repos_actions_runs_by_owner_repo(@project&.owner&.login, @project&.identifier, {query: {workflow: "SonarScanner.yaml", ref: params[:branch]}})
|
||||
render_ok
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
class Api::V1::UserTokensController < Api::V1::BaseController
|
||||
include AesCryptHelper
|
||||
before_action :require_login
|
||||
|
||||
def show
|
||||
password = decrypt(params[:password]) rescue params[:password].to_s
|
||||
tip_exception("密码不正确") unless current_user.check_password?(password)
|
||||
render_ok({access_token: current_user.gitea_token})
|
||||
end
|
||||
end
|
||||
|
|
@ -4,7 +4,7 @@ class Api::V1::Users::FeedbacksController < Api::V1::BaseController
|
|||
before_action :check_auth_for_observe_user
|
||||
|
||||
def create
|
||||
@result = Api::V1::Users::Feedbacks::CreateService.call(@observe_user, feedback_params)
|
||||
@result = Api::V1::Users::Feedbacks::CreateService.call(@observe_user, feedback_params, request.remote_ip)
|
||||
return render_error("反馈意见创建失败.") if @result.nil?
|
||||
return render_ok
|
||||
end
|
||||
|
|
|
|||
|
|
@ -313,8 +313,13 @@ class ApplicationController < ActionController::Base
|
|||
header = request.authorization
|
||||
pattern = /^Bearer /i
|
||||
token = header.gsub(pattern, "")
|
||||
User.current, message = Bot.decode_jwt_token(token)
|
||||
tip_exception(401, message) if message.present?
|
||||
user = User.find_by(gitea_token: token)
|
||||
if user.present?
|
||||
User.current = user
|
||||
else
|
||||
User.current, message = Bot.decode_jwt_token(token)
|
||||
tip_exception(401, message) if message.present?
|
||||
end
|
||||
else
|
||||
if @doorkeeper_token.present?
|
||||
# client方法对接,需要一直带着用户标识uid
|
||||
|
|
@ -326,24 +331,14 @@ class ApplicationController < ActionController::Base
|
|||
end
|
||||
end
|
||||
end
|
||||
elsif params[:access_token].present?
|
||||
user = User.find_by(gitea_token: params[:access_token])
|
||||
tip_exception(401, "无效token") if user.blank?
|
||||
User.current = user
|
||||
else
|
||||
User.current = find_current_user
|
||||
uid_logger("user_setup: " + (User.current.logged? ? "#{User.current.try(:login)} (id=#{User.current.try(:id)})" : "anonymous"))
|
||||
|
||||
# # 开放课程通过链接访问的用户
|
||||
# if !User.current.logged? && !params[:chinaoocTimestamp].blank? && !params[:websiteName].blank? && !params[:chinaoocKey].blank?
|
||||
# content = "#{OPENKEY}#{params[:websiteName]}#{params[:chinaoocTimestamp]}"
|
||||
#
|
||||
# if Digest::MD5.hexdigest(content) == params[:chinaoocKey]
|
||||
# user = open_class_user
|
||||
# if user
|
||||
# start_user_session(user)
|
||||
# set_autologin_cookie(user)
|
||||
# end
|
||||
# User.current = user
|
||||
# end
|
||||
# end
|
||||
|
||||
if !User.current.logged? && Rails.env.development?
|
||||
user = User.find 1
|
||||
User.current = user
|
||||
|
|
@ -366,6 +361,7 @@ class ApplicationController < ActionController::Base
|
|||
end
|
||||
end
|
||||
end
|
||||
UserOnline.login(User.current.id)
|
||||
# User.current = User.find 81403
|
||||
end
|
||||
|
||||
|
|
@ -602,7 +598,7 @@ class ApplicationController < ActionController::Base
|
|||
end
|
||||
|
||||
def find_user_with_id
|
||||
@user = User.find_by(type: 'User', id: params[:user_id])
|
||||
@user = User.find_by(type: 'User', id: params[:user_id]) || User.find_by(type: 'User', login: params[:login])
|
||||
# render_not_found("未找到’#{params[:login]}’相关的用户") unless @user
|
||||
render_error("未找到相关的用户") unless @user
|
||||
end
|
||||
|
|
|
|||
|
|
@ -31,12 +31,10 @@ class AttachmentsController < ApplicationController
|
|||
|
||||
def get_file
|
||||
Rails.logger.info("request.host===#{request.host},request.referer===#{request.referer}")
|
||||
tip_exception(403, "你没有权限访问") if request.host.present? && !request.referer.to_s.include?(request.host.to_s.gsub("www.",""))
|
||||
# tip_exception(403, "你没有权限访问") if request.host.present? && !request.referer.to_s.include?(request.host.to_s.gsub("www.",""))
|
||||
normal_status(-1, "参数缺失") if params[:download_url].blank?
|
||||
tip_exception('不可访问') if params[:download_url].to_s.include?("chinese_dictionary.txt")
|
||||
url = base_url.starts_with?("https:") ? params[:download_url].to_s.gsub("http:", "https:") : params[:download_url].to_s
|
||||
md5_file = Digest::MD5.hexdigest(params[:download_url])
|
||||
FileUtils.mkdir_p("#{Rails.root}#{EduSetting.get("attachment_folder")}gitea/") unless Dir.exists?("#{Rails.root}#{EduSetting.get("attachment_folder")}gitea/")
|
||||
tmp_path = "#{Rails.root}#{EduSetting.get("attachment_folder")}gitea/#{Time.now.strftime('%Y%m%d')}-#{md5_file}"
|
||||
if url.starts_with?(base_url) && !url.starts_with?("#{base_url}/repo")
|
||||
domain = GiteaService.gitea_config[:domain]
|
||||
api_url = GiteaService.gitea_config[:base_url]
|
||||
|
|
@ -45,18 +43,23 @@ class AttachmentsController < ApplicationController
|
|||
url.gsub!(url.split("/")[-1], '')
|
||||
# Rails.logger.info("url===#{url}")
|
||||
Rails.logger.info(filepath)
|
||||
ref = ref.blank? ? "" : URI.escape(ref.split('ref=')[1])
|
||||
request_url = [domain, api_url, URI.encode(url), URI.escape(filepath), "?ref=#{ref}&access_token=#{User.where(admin: true).take&.gitea_token}"].join
|
||||
request_url = [domain, api_url, URI.encode(url), URI.escape(filepath), "?ref=#{URI.escape(ref.split('ref=')[1])}&access_token=#{User.where(admin: true).take&.gitea_token}"].join
|
||||
Rails.logger.info("request_url===#{request_url}")
|
||||
File.delete(tmp_path) if File.exist?(tmp_path) # 删除之前的文件
|
||||
Util.download_file(request_url, tmp_path)
|
||||
filename = filepath
|
||||
suffix = request_url.split("?").first.split(".").last
|
||||
suffix_arr = ["zip", "rar", "xls", "xlsx", "pdf", "doc", "docx", "exe"] # 非文本文件直接重定向下载
|
||||
Rails.logger.info("suffix===#{suffix},#{suffix_arr.include?(suffix.to_s.downcase)}")
|
||||
if suffix_arr.include?(suffix.to_s.downcase)
|
||||
redirect_to request_url
|
||||
return
|
||||
else
|
||||
response = Faraday.get(request_url)
|
||||
filename = filepath
|
||||
end
|
||||
else
|
||||
File.delete(tmp_path) if File.exist?(tmp_path) # 删除之前的文件
|
||||
Util.download_file(URI.encode(url), tmp_path)
|
||||
response = Faraday.get(URI.encode(url))
|
||||
filename = params[:download_url].to_s.split("/").pop()
|
||||
end
|
||||
send_file(tmp_path, filename: filename, type: "application/octet-stream", disposition: 'attachment')
|
||||
send_data(response.body.force_encoding("UTF-8"), filename: filename, type: "application/octet-stream", disposition: 'attachment')
|
||||
end
|
||||
|
||||
def create
|
||||
|
|
|
|||
|
|
@ -16,13 +16,18 @@ class CommitLogsController < ApplicationController
|
|||
project = Project.where(identifier: repository_name).where(user_id: owner&.id)&.first
|
||||
project = Project.where(identifier: repository_name).where(gpid: repository_id)&.first if project.blank?
|
||||
project.update_column(:updated_on, Time.now) if project.present?
|
||||
if project.project_type == 'sync_mirror'
|
||||
render_ok
|
||||
return
|
||||
end
|
||||
params[:commits].each do |commit|
|
||||
commit_id = commit[:id]
|
||||
message = commit[:message]
|
||||
commit_date = Time.parse(commit[:timestamp]) || Time.now
|
||||
commit_log = CommitLog.create(user: user, project: project, repository_id: repository_id,
|
||||
name: repository_name, full_name: repository_full_name,
|
||||
ref: ref, commit_id: commit_id, message: message)
|
||||
commit_log.project_trends.create(user_id: user.id, project_id: project&.id, action_type: "create") if user.id !=2
|
||||
ref: ref, commit_id: commit_id, message: message, created_at: commit_date, updated_at: commit_date)
|
||||
commit_log.project_trends.create(user_id: user.id, project_id: project&.id, action_type: "create") if user.present? && user.id !=2 && project.present?
|
||||
# 统计数据新增
|
||||
CacheAsyncSetJob.perform_later("project_common_service", {commits: 1}, project.id)
|
||||
|
||||
|
|
@ -36,6 +41,7 @@ class CommitLogsController < ApplicationController
|
|||
solve_issue_content = message.to_s.scan(/\b(Fix|Fixes|Fixed|Fixing|fix|fixes|fixed|fixing|Resolve|Resolves|Resolved|Resolving|resolve|resolves|resolved|resolving|Implement|Implements|Implemented|Implementing|implement|implements|implemented|implementing)\s*(#\d+(,\s*#\d+)*)?\b/)
|
||||
ChangeIssueStatusByMessageJob.perform_later(commit_id, project, commit_user, solve_issue_content[0][1], 3) if solve_issue_content[0].present? && solve_issue_content[0][1].present?
|
||||
end
|
||||
render_ok
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,169 @@
|
|||
require 'yaml'
|
||||
require 'json'
|
||||
|
||||
module Api::ActionValidatorHelper
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
def validate_string(yaml_string, branch, default_branch)
|
||||
begin
|
||||
yaml_content = YAML.safe_load(yaml_string)
|
||||
validate_content(yaml_content, branch, default_branch)
|
||||
rescue Psych::SyntaxError => e
|
||||
{ valid: false, errors: ["YAML语法错误: #{e.message}"] }
|
||||
rescue => e
|
||||
{ valid: false, errors: ["数据读取错误: #{e.message}"] }
|
||||
end
|
||||
end
|
||||
|
||||
def validate_content(data, branch, default_branch)
|
||||
errors = []
|
||||
warnings = []
|
||||
|
||||
# 基本结构验证
|
||||
errors.concat(validate_basic_structure(data))
|
||||
|
||||
# 触发器验证
|
||||
errors.concat(validate_trigger(data, branch, default_branch))
|
||||
|
||||
# 任务验证
|
||||
errors.concat(validate_job(data))
|
||||
|
||||
# 步骤验证
|
||||
if data['jobs']
|
||||
data['jobs'].each do |job_name, job_config|
|
||||
errors.concat(validate_job_steps(job_name, job_config))
|
||||
end
|
||||
end
|
||||
|
||||
{
|
||||
valid: errors.empty?,
|
||||
errors: errors,
|
||||
warnings: warnings,
|
||||
job_count: data['jobs']&.size || 0
|
||||
}
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def validate_basic_structure(data)
|
||||
errors = []
|
||||
|
||||
unless data.is_a?(Hash)
|
||||
errors << "Action文件必须是YAML对象"
|
||||
return errors
|
||||
end
|
||||
|
||||
unless data.key?('name')
|
||||
errors << "缺少必需字段: name"
|
||||
end
|
||||
|
||||
unless data.key?(true)
|
||||
errors << "缺少触发器配置: on"
|
||||
end
|
||||
|
||||
unless data.key?('jobs')
|
||||
errors << "缺少任务配置: jobs"
|
||||
end
|
||||
|
||||
errors
|
||||
end
|
||||
|
||||
def validate_trigger(data, branch, default_branch)
|
||||
errors = []
|
||||
Rails.logger.info "data==#{data}"
|
||||
Rails.logger.info "data==true#{data[true]}"
|
||||
if data[true]
|
||||
if data[true]['push']
|
||||
# unless data[true]['push'].key?('branches')
|
||||
# errors << "push触发器缺少branches配置"
|
||||
# end
|
||||
#
|
||||
# unless data[true]['push'].key?('paths-ignore')
|
||||
# errors << "push触发器缺少paths-ignore配置"
|
||||
# end
|
||||
end
|
||||
if data[true]['schedule'] && branch != default_branch
|
||||
errors << "只有#{default_branch}分支支持定时触发器"
|
||||
end
|
||||
end
|
||||
|
||||
errors
|
||||
end
|
||||
|
||||
def validate_job(data)
|
||||
errors = []
|
||||
|
||||
if data['jobs']
|
||||
jobs = data['jobs']
|
||||
|
||||
unless jobs.is_a?(Hash)
|
||||
errors << "jobs字段必须是对象"
|
||||
return errors
|
||||
end
|
||||
|
||||
jobs.each do |job_name, job_config|
|
||||
unless job_config.is_a?(Hash)
|
||||
errors << "任务 #{job_name} 配置必须是对象"
|
||||
next
|
||||
end
|
||||
|
||||
# unless job_config.key?('name')
|
||||
# errors << "任务 #{job_name} 缺少name字段"
|
||||
# end
|
||||
|
||||
unless job_config.key?('runs-on')
|
||||
errors << "任务 #{job_name} 缺少runs-on字段"
|
||||
end
|
||||
|
||||
unless job_config.key?('steps')
|
||||
errors << "任务 #{job_name} 缺少steps字段"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
errors
|
||||
end
|
||||
|
||||
def validate_job_steps(job_name, job_config)
|
||||
errors = []
|
||||
steps = job_config['steps'] || []
|
||||
|
||||
unless steps.is_a?(Array)
|
||||
errors << "任务 #{job_name} 的steps必须是数组"
|
||||
return errors
|
||||
end
|
||||
# 验证每个步骤的详细配置
|
||||
steps.each_with_index do |step, index|
|
||||
errors.concat(validate_step(job_name, step, index))
|
||||
end
|
||||
|
||||
errors
|
||||
end
|
||||
|
||||
def validate_step(job_name, step, index)
|
||||
errors = []
|
||||
|
||||
unless step.is_a?(Hash)
|
||||
errors << "任务 #{job_name} 步骤 #{index + 1} 必须是对象"
|
||||
return errors
|
||||
end
|
||||
|
||||
# unless step.key?('name')
|
||||
# errors << "任务 #{job_name} 步骤 #{index + 1} 缺少name字段"
|
||||
# end
|
||||
|
||||
# 验证uses或run字段
|
||||
has_uses = step.key?('uses')
|
||||
has_run = step.key?('run')
|
||||
|
||||
unless has_uses || has_run
|
||||
errors << "任务 #{job_name} 步骤 #{index + 1} 必须包含uses或run字段"
|
||||
end
|
||||
|
||||
if has_uses && has_run
|
||||
errors << "任务 #{job_name} 步骤 #{index + 1} 不能同时包含uses和run字段"
|
||||
end
|
||||
|
||||
errors
|
||||
end
|
||||
end
|
||||
|
|
@ -63,6 +63,7 @@ module LoginHelper
|
|||
|
||||
user.delete_autologin_token(autologin)
|
||||
user.delete_session_token(session[:tk])
|
||||
UserOnline.logout(User.current.id)
|
||||
self.logged_user = nil
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -513,7 +513,7 @@ class IssuesController < ApplicationController
|
|||
end
|
||||
|
||||
def set_issue
|
||||
@issue = Issue.find_by_id(params[:id])
|
||||
@issue = @project.issues.issue_issue.where(project_issues_index: params[:id]).where.not(id: params[:id]).take || @project.issues.issue_issue.find_by_id(params[:id])
|
||||
if @issue.blank?
|
||||
return render_not_found
|
||||
elsif !(@project.is_public || (current_user.present? && (@project.member?(current_user) || current_user&.admin? || (@project.user_id == current_user&.id))))
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ class JournalsController < ApplicationController
|
|||
AtmeService.call(current_user, @atme_receivers, journal) if @atme_receivers.size > 0
|
||||
TouchWebhookJob.set(wait: 5.seconds).perform_later('PullRequestComment', @issue&.id, current_user.id, journal.id, 'created', {})
|
||||
# @issue.project_trends.create(user_id: current_user.id, project_id: @project.id, action_type: "journal")
|
||||
|
||||
ProjectActions::PullRequestReviewCommentEvent.build(@issue.project, current_user, @issue.pull_request, journal) if @issue.issue_classify == "pull_request"
|
||||
# author: zxh
|
||||
# 调用上链API
|
||||
push_activity_2_blockchain("issue_comment_create", journal) if Site.has_blockchain? && @project.use_blockchain
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ class MainController < ApplicationController
|
|||
skip_before_action :setup_laboratory
|
||||
|
||||
def first_stamp
|
||||
render :json => { status: 0, message: Time.now.to_i }
|
||||
render :json => { status: 0, message: Time.now.to_i, online: UserOnline.count }
|
||||
end
|
||||
|
||||
def test_404
|
||||
|
|
|
|||
|
|
@ -71,4 +71,8 @@ class Oauth::BaseController < ActionController::Base
|
|||
Rails.logger.info("[educoder] set sesstion edulogin: #{login}")
|
||||
session[:edulogin] = login
|
||||
end
|
||||
|
||||
def go_page_by_cookie(new_user)
|
||||
cookies["go_page"].present? ? cookies["go_page"] : root_path(new_user: new_user)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ class Oauth::CallbacksController < Oauth::BaseController
|
|||
"OpenUsers::#{platform.to_s.capitalize}".constantize.create!(user: current_user, uid: login, extra: auth_hash.extra)
|
||||
end
|
||||
end
|
||||
redirect_to root_path(new_user: new_user)
|
||||
redirect_to go_page_by_cookie(new_user)
|
||||
end
|
||||
|
||||
def process_callback_new
|
||||
|
|
@ -69,7 +69,7 @@ class Oauth::CallbacksController < Oauth::BaseController
|
|||
open_user = "OpenUsers::#{platform.to_s.capitalize}".constantize.find_by(uid: uid)
|
||||
if open_user.present? && open_user.user.present?
|
||||
successful_authentication(open_user.user)
|
||||
redirect_to root_path(new_user: false)
|
||||
redirect_to go_page_by_cookie(false)
|
||||
return
|
||||
else
|
||||
if current_user.blank? || !current_user.logged?
|
||||
|
|
|
|||
|
|
@ -0,0 +1,61 @@
|
|||
class Oauth::CcfController < Oauth::BaseController
|
||||
include RegisterHelper
|
||||
|
||||
def oauth_url
|
||||
redirect_to Ccf::Service.oauth_url
|
||||
end
|
||||
|
||||
# 需要educoder那边设置回调地址
|
||||
def create
|
||||
begin
|
||||
code = params['_access_code'].to_s.strip
|
||||
tip_exception("_access_code不能为空") if code.blank?
|
||||
|
||||
# {"code":"1","msg":"success","data":{"token":"cef9607dc43540e4a75cc484b2d42a24","id":"3a267da772c068866bde35fee6efff42","openId":"","unionId":"","loginName":"肖小琼","username":"13429151265","name":"肖小琼","cardNumber":null,"email":null,"userState":"2","contact":"13429151265","gender":null,"englishName":"xiaoxiaoqiong","timeForNow":null,"roleCodes":"07","roleNames":"注册专业会员","regTime":1766375090000,"effDate":null,"lifeLongState":"2","committees":[]}}
|
||||
new_user = false
|
||||
# token = Ccf::Service.access_token(code)
|
||||
# Rails.logger.info("[OAuth2] result -> #{token}")
|
||||
result = Ccf::Service.user_info(code)
|
||||
tip_exception("请求用户信息错误") if result['code'].to_i != 1
|
||||
user_info = result['data']
|
||||
login = Pinyin.t(user_info['loginName'], splitter: '') || user_info['username']
|
||||
email = user_info['email']
|
||||
# 存在该用户
|
||||
open_user = OpenUsers::Ccf.find_by(uid: login)
|
||||
if open_user.present? && open_user.user.present?
|
||||
successful_authentication(open_user.user)
|
||||
else
|
||||
if current_user.blank? || !current_user.logged?
|
||||
# 优先手机号匹配用户
|
||||
has_user = nil
|
||||
has_user = User.find_by(phone: user_info['contact']) if user_info['contact'].present?
|
||||
has_user = User.find_by(mail: email) if has_user.blank? && email.present?
|
||||
if has_user.present?
|
||||
OpenUsers::Ccf.create!(user_id: has_user.id, uid: login, extra: result)
|
||||
successful_authentication(has_user)
|
||||
else
|
||||
new_user = true
|
||||
session[:unionid] = user_info['username']
|
||||
##如果用户名被占用,重新生成
|
||||
login = User.generate_user_login('p') if User.find_by(login: login).present?
|
||||
email = "#{login}@forge.com" if email.blank?
|
||||
reg_result = autologin_register(login, email, "Ec#{User.generate_user_login('p')}2021#", 'ccf', user_info['contact'], user_info['name'])
|
||||
Rails.logger.info("[OAuth2] reg_result -> #{reg_result}")
|
||||
if reg_result[:message].blank?
|
||||
open_user = OpenUsers::Ccf.create!(user_id: reg_result[:user][:id], uid: login, extra: user_info)
|
||||
successful_authentication(open_user.user)
|
||||
else
|
||||
tip_exception(reg_result[:message])
|
||||
end
|
||||
end
|
||||
else
|
||||
OpenUsers::Ccf.create!(user: current_user, uid: login, extra: user_info)
|
||||
end
|
||||
end
|
||||
Rails.logger.info("[OAuth2] session[:unionid] -> #{session[:unionid]}")
|
||||
redirect_to go_page_by_cookie(new_user)
|
||||
rescue Exception => ex
|
||||
render_error(ex.message)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -22,7 +22,7 @@ class Oauth::Ci4sController < Oauth::BaseController
|
|||
open_user = OpenUsers::Ci4s.find_by(uid: user_info['username'])
|
||||
if open_user.present? && open_user.user.present?
|
||||
successful_authentication(open_user.user)
|
||||
redirect_to root_path(new_user: false)
|
||||
redirect_to go_page_by_cookie(false)
|
||||
return
|
||||
else
|
||||
if current_user.blank? || !current_user.logged?
|
||||
|
|
@ -45,7 +45,7 @@ class Oauth::Ci4sController < Oauth::BaseController
|
|||
end
|
||||
end
|
||||
Rails.logger.info("[OAuth2] session[:unionid] -> #{session[:unionid]}")
|
||||
redirect_to root_path(new_user: new_user)
|
||||
redirect_to go_page_by_cookie(new_user)
|
||||
rescue Exception => ex
|
||||
render_error(ex.message)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ class Oauth::EducoderController < Oauth::BaseController
|
|||
open_user = OpenUsers::Educoder.find_by(uid: result['login'])
|
||||
if open_user.present? && open_user.user.present?
|
||||
successful_authentication(open_user.user)
|
||||
redirect_to root_path(new_user: false)
|
||||
redirect_to go_page_by_cookie(false)
|
||||
return
|
||||
else
|
||||
if current_user.blank? || !current_user.logged?
|
||||
|
|
@ -71,7 +71,7 @@ class Oauth::EducoderController < Oauth::BaseController
|
|||
Rails.logger.info("[OAuth2] session[:unionid] -> #{session[:unionid]}")
|
||||
redirect_to "/bindlogin/educoder"
|
||||
|
||||
# redirect_to root_path(new_user: new_user)
|
||||
# redirect_to go_page_by_cookie(new_user)
|
||||
rescue Exception => ex
|
||||
render_error(ex.message)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,88 @@
|
|||
class Oauth::OpeniController < Oauth::BaseController
|
||||
def bind
|
||||
begin
|
||||
login = params[:login]
|
||||
mail = params[:mail] || nil
|
||||
callback_url = params[:callback_url]
|
||||
token = params[:token]
|
||||
|
||||
::OauthEducoderForm.new({ login: login, token: token, callback_url: callback_url }).validate!
|
||||
|
||||
open_user = OpenUsers::Openi.find_by(uid: login) || OpenUsers::Openi.find_by(uid: mail)
|
||||
|
||||
if open_user.present? && open_user.user.present? && open_user.user.email_binded?
|
||||
Rails.logger.info "######## open_user exist and open_user.user exsit and email is binded ok"
|
||||
successful_authentication(open_user.user)
|
||||
|
||||
redirect_to callback_url
|
||||
else
|
||||
Rails.logger.info "######## open user not exits"
|
||||
user = User.find_by(login: login) || User.find_by(mail: mail)
|
||||
|
||||
if user.is_a?(User) && !user.is_a?(AnonymousUser)
|
||||
OpenUsers::Openi.create!(user: user, uid: login)
|
||||
successful_authentication(user)
|
||||
|
||||
redirect_to callback_url
|
||||
else
|
||||
redirect_to oauth_register_path(login: login, mail: mail, callback_url: callback_url)
|
||||
end
|
||||
end
|
||||
rescue WechatOauth::Error => ex
|
||||
render_error(ex.message)
|
||||
end
|
||||
end
|
||||
|
||||
# 需要gitlink那边设置回调地址
|
||||
def create
|
||||
# begin
|
||||
code = params['code'].to_s.strip
|
||||
tip_exception("code不能为空") if code.blank?
|
||||
|
||||
result = OpeniOauth::Service.access_token(code)
|
||||
Rails.logger.info("[Openi] [access_token result] #{result} ")
|
||||
tip_exception("获取授权Token失败") if result.blank? || result[:access_token].blank?
|
||||
result = OpeniOauth::Service.user_info(result[:access_token])
|
||||
Rails.logger.info("[Openi] [user_info result] #{result} ")
|
||||
|
||||
# 存在该用户
|
||||
login = result['login']
|
||||
mail = result['email']
|
||||
nickName = result['full_name'] || result['username']
|
||||
new_user = false
|
||||
# 存在该用户
|
||||
open_user = OpenUsers::Openi.find_by(uid: login)
|
||||
if open_user.present? && open_user.user.present?
|
||||
successful_authentication(open_user.user)
|
||||
else
|
||||
if current_user.blank? || !current_user.logged?
|
||||
has_user = User.find_by(mail: mail)
|
||||
if has_user.present?
|
||||
OpenUsers::Openi.create!(user_id: has_user.id, uid: login, extra: result)
|
||||
successful_authentication(has_user)
|
||||
else
|
||||
new_user = true
|
||||
##如果用户名被占用,重新生成
|
||||
login = User.generate_user_login('p') if User.find_by(login: login).present?
|
||||
mail = "#{login}@example.org" if mail.blank?
|
||||
reg_result = autologin_register(login, mail, "Ec#{User.generate_user_login('p')}2021#", 'openi', nil, nickName)
|
||||
Rails.logger.info("[Openi] [reg_result] #{reg_result} ")
|
||||
if reg_result[:message].blank?
|
||||
open_user = OpenUsers::Openi.create!(user_id: reg_result[:user][:id], uid: login, extra: result)
|
||||
successful_authentication(open_user.user)
|
||||
else
|
||||
tip_exception(reg_result.present? ? reg_result[:message] : "授权失败")
|
||||
end
|
||||
end
|
||||
else
|
||||
OpenUsers::Openi.create!(user: current_user, uid: login, extra: result)
|
||||
end
|
||||
end
|
||||
redirect_to go_page_by_cookie(new_user)
|
||||
# rescue Exception => ex
|
||||
# render_error(ex.message)
|
||||
# end
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
class Oauth2Controller < ActionController::Base
|
||||
class Oauth2Controller < ApplicationController
|
||||
layout 'doorkeeper/application'
|
||||
include LoginHelper
|
||||
|
||||
|
|
@ -9,6 +9,12 @@ class Oauth2Controller < ActionController::Base
|
|||
end
|
||||
|
||||
def create
|
||||
if User.current.logged?
|
||||
to_url = params[:call_url] + "&auth=" + User.current.login
|
||||
to_url = params[:call_url] + "&auth=" + User.current.login + "&state=" + params[:state] if params[:state].present?
|
||||
redirect_to to_url
|
||||
return
|
||||
end
|
||||
if params[:login].blank?
|
||||
@error = {msg: '邮箱地址或用户名不能为空', id: 'login'}
|
||||
elsif params[:password].blank?
|
||||
|
|
@ -33,7 +39,9 @@ class Oauth2Controller < ActionController::Base
|
|||
return
|
||||
end
|
||||
login_control.clear
|
||||
redirect_to params[:call_url] + "&auth=" + @user.login
|
||||
to_url = params[:call_url] + "&auth=" + @user.login
|
||||
to_url = params[:call_url] + "&auth=" + @user.login + "&state=" + params[:state] if params[:state].present?
|
||||
redirect_to to_url
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -107,8 +107,10 @@ class Organizations::OrganizationsController < Organizations::BaseController
|
|||
tip_exception("密码不正确") unless current_user.check_password?(password)
|
||||
ActiveRecord::Base.transaction do
|
||||
gitea_destroy = Gitea::Organization::DeleteService.call(current_user.gitea_token, @organization.login)
|
||||
if gitea_destroy[:status] == 204
|
||||
if gitea_destroy[:status] == 204
|
||||
data_bank = @organization.attributes.to_json
|
||||
@organization.destroy!
|
||||
UserAction.create(action_id: @organization.id, action_type: "DestroyOrganization", user_id: current_user.id, :ip => request.remote_ip, data_bank: data_bank)
|
||||
render_ok
|
||||
elsif gitea_destroy[:status] == 500
|
||||
tip_exception("当组织内含有仓库时,无法删除此组织")
|
||||
|
|
|
|||
|
|
@ -18,6 +18,23 @@ class Organizations::ProjectsController < Organizations::BaseController
|
|||
@projects = paginate(@projects)
|
||||
end
|
||||
|
||||
def create
|
||||
ActiveRecord::Base.transaction do
|
||||
org_project_params = project_params.merge({ user_id: @organization.id })
|
||||
Projects::CreateForm.new(org_project_params).validate!
|
||||
@project = Projects::CreateService.new(current_user, org_project_params).call
|
||||
OpenProjectDevOpsJob.set(wait: 5.seconds).perform_later(@project&.id, current_user.id)
|
||||
UpdateProjectTopicJob.perform_later(@project.id) if @project.id.present?
|
||||
end
|
||||
rescue Gitea::Api::ServerError => ex
|
||||
uid_logger_error(ex.message)
|
||||
# tip_exception(ex.http_code, ex.message)
|
||||
tip_exception(ex.message)
|
||||
rescue ApplicationService::Error => e
|
||||
uid_logger_error(e.message)
|
||||
tip_exception(e.message)
|
||||
end
|
||||
|
||||
def search
|
||||
tip_exception("请输入搜索关键词") if params[:search].nil?
|
||||
# 表情处理
|
||||
|
|
@ -48,4 +65,10 @@ class Organizations::ProjectsController < Organizations::BaseController
|
|||
def sort_direction
|
||||
%w(desc asc).include?(params[:sort_direction]) ? params[:sort_direction] : 'desc'
|
||||
end
|
||||
|
||||
def project_params
|
||||
params.permit(:name, :description, :repository_name, :website, :lesson_url, :default_branch, :identifier,
|
||||
:project_category_id, :project_language_id, :license_id, :ignore_id, :private, :has_actions,
|
||||
:blockchain, :blockchain_token_all, :blockchain_init_token, :pr_view_admin)
|
||||
end
|
||||
end
|
||||
|
|
@ -11,8 +11,9 @@ class OwnersController < ApplicationController
|
|||
end
|
||||
|
||||
def show
|
||||
# login = params[:id].to_s[0..-6]
|
||||
login = params[:id].to_s
|
||||
# 如果 id 包含格式扩展名(如 .json),移除它
|
||||
login = login.sub(/\.(json|html|xml|csv|pdf|png|jpg|jpeg|gif|txt)$/, '')
|
||||
@owner = Owner.find_by(login: login) || Owner.find_by(id: login)
|
||||
clear_user_cookie unless @owner.present?
|
||||
return render_not_found unless @owner.present?
|
||||
|
|
@ -45,6 +46,7 @@ class OwnersController < ApplicationController
|
|||
org_projects = Project.joins(team_projects: [team: :team_users]).where(team_users: {user_id: @owner.id}).to_sql
|
||||
projects = Project.from("( #{ normal_projects} UNION #{ org_projects } ) AS projects").distinct
|
||||
user_projects = User.current.logged? && (User.current.admin? || User.current.login == @owner.login) ? projects : projects.visible
|
||||
@user_projects_count = user_projects.size
|
||||
@projects_common_count = user_projects.common.size
|
||||
@projects_mirrior_count = user_projects.mirror.size
|
||||
@projects_sync_mirrior_count = user_projects.sync_mirror.size
|
||||
|
|
|
|||
|
|
@ -3,43 +3,72 @@ class ProjectTrendsController < ApplicationController
|
|||
before_action :check_project_public, except: [:last]
|
||||
|
||||
def index
|
||||
project_trends = @project.project_trends.preload(:user, trend: :user, project: :owner)
|
||||
@project_trends = @project.project_trends.preload(:user, trend: :user, project: :owner).order(created_at: :desc)
|
||||
|
||||
check_time = params[:time] #时间的筛选
|
||||
check_type = params[:type] #动态类型的筛选,目前已知的有 Issue, PullRequest, Version
|
||||
check_status = params[:status] #类型的选择 "create", "close", "journal",
|
||||
check_time = params[:time]&.to_i #时间的筛选
|
||||
check_type = params[:type]&.strip #动态类型的筛选,目前已知的有 Issue, PullRequest, Version
|
||||
check_status = params[:status] #类型的选择 "create", "close", "journal",
|
||||
|
||||
|
||||
# 构建基础查询条件
|
||||
scope = @project_trends
|
||||
|
||||
# 时间筛选
|
||||
if check_time.present?
|
||||
check_time = check_time.to_i
|
||||
project_trends = project_trends.where("created_at between ? and ?",(Time.now.beginning_of_day - check_time.days), Time.now.end_of_day)
|
||||
start_time = Time.now.beginning_of_day - check_time.days
|
||||
end_time = Time.now.end_of_day
|
||||
scope = scope.where(created_at: start_time..end_time)
|
||||
end
|
||||
|
||||
@project_close_issues_count = project_trends.where(trend_type: "Issue", action_type: "close").size
|
||||
@project_issues_count = project_trends.where(trend_type: "Issue", action_type: "create").size
|
||||
@project_open_issues_count = @project_issues_count - @project_close_issues_count
|
||||
# 提前计算统计信息(避免重复查询)
|
||||
if check_type.blank? && check_status.blank?
|
||||
# 使用单次查询获取所有统计信息
|
||||
stats = scope.select(
|
||||
"user_id", "trend_type", "trend_id", "action_type", "project_id",
|
||||
"COUNT(*) as total",
|
||||
"COUNT(CASE WHEN trend_type = 'Issue' AND action_type = 'close' THEN 1 END) as closed_issues",
|
||||
"COUNT(CASE WHEN trend_type = 'Issue' AND action_type = 'create' THEN 1 END) as created_issues",
|
||||
"COUNT(CASE WHEN trend_type = 'PullRequest' AND action_type IN ('close', 'merge') THEN 1 END) as closed_prs",
|
||||
"COUNT(CASE WHEN trend_type = 'PullRequest' AND action_type = 'create' THEN 1 END) as created_prs"
|
||||
).take
|
||||
|
||||
@project_close_issues_count = stats.closed_issues
|
||||
@project_issues_count = stats.created_issues
|
||||
@project_open_issues_count = @project_issues_count - @project_close_issues_count
|
||||
@project_pr_count = stats.closed_prs
|
||||
@project_pr_all_count = stats.created_prs
|
||||
@project_new_pr_count = @project_pr_all_count - @project_pr_count
|
||||
end
|
||||
|
||||
@project_pr_count = project_trends.where(trend_type: "PullRequest", action_type: ["close", "merge"]).size
|
||||
@project_pr_all_count = project_trends.where(trend_type: "PullRequest", action_type: "create").size
|
||||
@project_new_pr_count = @project_pr_all_count - @project_pr_count
|
||||
# 类型筛选
|
||||
if check_type.present?
|
||||
project_trends = project_trends.where(trend_type: check_type.to_s.strip)
|
||||
scope = scope.where(trend_type: check_type)
|
||||
end
|
||||
|
||||
# 状态筛选
|
||||
if check_status.present?
|
||||
if check_status == "delay" || check_status == "close"
|
||||
project_trends = project_trends.where(action_type: ["close", "merge"])
|
||||
else
|
||||
project_trends = project_trends.where(action_type: ["create"]).where.not(trend_id: project_trends.where(action_type: ["close", "merge"]).pluck(:trend_id))
|
||||
case check_status
|
||||
when "delay", "close"
|
||||
scope = scope.where(action_type: ["close", "merge"])
|
||||
when "create"
|
||||
# 使用子查询优化,避免重复扫描表
|
||||
closed_trend_ids = scope.where(action_type: ["close", "merge"]).select(:trend_id)
|
||||
scope = scope.where(action_type: "create")
|
||||
.where.not(trend_id: closed_trend_ids)
|
||||
else
|
||||
# 其他状态的处理
|
||||
scope = scope.where(action_type: check_status)
|
||||
end
|
||||
else
|
||||
project_trends = project_trends.where(action_type: "create")
|
||||
# 默认只显示创建记录
|
||||
scope = scope.where(action_type: "create")
|
||||
end
|
||||
project_trends = project_trends.order("created_at desc")
|
||||
|
||||
@page = params[:page]
|
||||
# 获取总数和分页数据
|
||||
@project_trends_size = scope.size
|
||||
@page = params[:page] || 1
|
||||
@limit = params[:limit] || 15
|
||||
@project_trends_size = project_trends.size
|
||||
@project_trends = project_trends.page(@page).per(@limit)
|
||||
@project_trends = scope.page(@page).per(@limit)
|
||||
end
|
||||
|
||||
def last
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ class ProjectsController < ApplicationController
|
|||
if category_id.blank? && params[:search].blank? && params[:topic_id].blank? && params[:topic_name].blank?
|
||||
# 默认查询时count性能问题处理
|
||||
not_category_count = Project.where(project_category_id: nil).count
|
||||
ProjectCategory.sum("projects_count") - Project.visible.joins("left join organization_extensions on organization_extensions.organization_id = projects.user_id").where("organization_extensions.visibility =2").count + not_category_count
|
||||
ProjectCategory.sum("projects_count") + not_category_count - Project.visible.joins("left join organization_extensions on organization_extensions.organization_id = projects.user_id").where("organization_extensions.visibility =2").where(status: 1).count - Project.where(status: 0).count - Project.is_private.where(status:1).count
|
||||
elsif params[:search].present? || params[:topic_id].present? || params[:topic_name].present?
|
||||
@projects.total_count
|
||||
else
|
||||
|
|
@ -83,14 +83,21 @@ class ProjectsController < ApplicationController
|
|||
if EduSetting.get("mirror_address").to_s.include?("github") && enable_accelerator?(mirror_params[:clone_addr])
|
||||
source_clone_url = mirror_params[:clone_addr]
|
||||
uid_logger("########## 已动加速器 ##########")
|
||||
result = Gitea::Accelerator::MigrateService.call(mirror_params)
|
||||
if result[:status] == :success
|
||||
Rails.logger.info "########## 加速镜像成功 ########## "
|
||||
Projects::MigrateService.call(current_user,
|
||||
mirror_params.merge(source_clone_url: source_clone_url,
|
||||
clone_addr: accelerator_url(mirror_params[:repository_name])))
|
||||
hasProject = Gitea::Accelerator::GetService.call("root", mirror_params[:repository_name])
|
||||
if hasProject.present? && hasProject["original_url"] == source_clone_url
|
||||
uid_logger("########## 已在加速器查询到#{source_clone_url} ##########")
|
||||
Projects::MigrateService.call(current_user, mirror_params.merge(source_clone_url: source_clone_url, clone_addr: accelerator_url(mirror_params[:repository_name])))
|
||||
else
|
||||
Projects::MigrateService.call(current_user, mirror_params)
|
||||
result = Gitea::Accelerator::MigrateService.call(mirror_params)
|
||||
uid_logger("########## 已动加速器#{result} ###########{mirror_params}")
|
||||
if result[:status] == :success
|
||||
Rails.logger.info "########## 加速镜像成功 ########## "
|
||||
Projects::MigrateService.call(current_user,
|
||||
mirror_params.merge(source_clone_url: source_clone_url,
|
||||
clone_addr: accelerator_url(mirror_params[:repository_name])))
|
||||
else
|
||||
Projects::MigrateService.call(current_user, mirror_params)
|
||||
end
|
||||
end
|
||||
elsif EduSetting.get("mirror_address").to_s.include?("cnpmjs") && mirror_params[:clone_addr].include?("github.com")
|
||||
source_clone_url = mirror_params[:clone_addr]
|
||||
|
|
@ -383,6 +390,24 @@ class ProjectsController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
def clone_detection
|
||||
forge_url = "#{Rails.application.config_for(:configuration)['platform_url']}"
|
||||
target_dir = "2-#{SecureRandom.hex(6)}"
|
||||
source_url = "#{forge_url}/#{@project.owner.name}/#{@project.identifier}.git"
|
||||
source_dir = "#{@project.id}-#{SecureRandom.hex(6)}"
|
||||
clone_dir = File.join(Rails.root, "public", "clone_detection")
|
||||
system("cd #{clone_dir} && git clone #{params[:target_url]} #{target_dir}")
|
||||
system("cd #{clone_dir} && git clone #{source_url} #{source_dir}")
|
||||
system("cd /var/www/NiCad-6.2 && ./nicad6cross functions java /var/www/forgeplus/public/clone_detection/#{source_dir} /var/www/forgeplus/public/clone_detection/#{target_dir}")
|
||||
view_url = "#{forge_url}/#{source_dir}_functions-blind-crossclones/#{source_dir}_functions-blind-crossclones-0.30-classes-withsource.html"
|
||||
system("rm -rf /var/www/forgeplus/public/clone_detection/#{source_dir}")
|
||||
system("rm -rf /var/www/forgeplus/public/clone_detection/#{target_dir}")
|
||||
render_ok({ view_url: view_url })
|
||||
rescue
|
||||
Rails.logger.info("clone_detection...............error,#{forge_url},#{source_url}")
|
||||
system("rm -rf /var/www/forgeplus/public/clone_detection/#{source_dir}")
|
||||
system("rm -rf /var/www/forgeplus/public/clone_detection/#{target_dir}")
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ class PullRequestsController < ApplicationController
|
|||
|
||||
def index
|
||||
# @issues = Gitea::PullRequest::ListService.new(@user,@repository.try(:identifier)).call #通过gitea获取
|
||||
ProjectTemplates::PullRequest.init_data(@project.id)
|
||||
issues = @project.issues.issue_pull_request.issue_index_includes.includes(pull_request: :user)
|
||||
issues = issues.where(is_private: false) unless current_user.present? && (current_user.admin? || @project.member?(current_user))
|
||||
@all_issues = issues.distinct
|
||||
|
|
@ -71,11 +72,11 @@ class PullRequestsController < ApplicationController
|
|||
@pull_request.bind_gitea_pull_request!(@gitea_pull_request[:body]["number"], @gitea_pull_request[:body]["id"])
|
||||
reviewers = User.where(id: params[:reviewer_ids])
|
||||
@pull_request.reviewers = reviewers
|
||||
SendTemplateMessageJob.perform_later('PullRequestAssigned', current_user.id, @pull_request&.id) if Site.has_notice_menu?
|
||||
SendTemplateMessageJob.perform_later('ProjectPullRequest', current_user.id, @pull_request&.id) if Site.has_notice_menu?
|
||||
SendTemplateMessageJob.set(wait: 5.seconds).perform_later('PullRequestAssigned', current_user.id, @pull_request&.id) if Site.has_notice_menu?
|
||||
SendTemplateMessageJob.set(wait: 5.seconds).perform_later('ProjectPullRequest', current_user.id, @pull_request&.id) if Site.has_notice_menu?
|
||||
Rails.logger.info "[ATME] maybe to at such users: #{@atme_receivers.pluck(:login)}"
|
||||
AtmeService.call(current_user, @atme_receivers, @pull_request) if @atme_receivers.size > 0
|
||||
|
||||
ProjectActions::PullRequestEvent.build(@project, current_user, @pull_request, "opened")
|
||||
# author: zxh
|
||||
# 调用上链API
|
||||
push_activity_2_blockchain("pull_request_create", @pull_request) if Site.has_blockchain? && @project.use_blockchain
|
||||
|
|
@ -93,6 +94,7 @@ class PullRequestsController < ApplicationController
|
|||
@fork_project_user_name = @pull_request&.fork_project&.owner.try(:show_real_name)
|
||||
@fork_project_user = @pull_request&.fork_project&.owner.try(:login)
|
||||
@fork_project_identifier = @pull_request&.fork_project&.repository.try(:identifier)
|
||||
@gitea_pull = Gitea::PullRequest::GetService.call(@owner.login, @repository.identifier, @pull_request.gitea_number, @owner&.gitea_token)
|
||||
end
|
||||
|
||||
def update
|
||||
|
|
@ -111,15 +113,51 @@ class PullRequestsController < ApplicationController
|
|||
@pull_request.reviewers = reviewers
|
||||
|
||||
if @issue.update_attributes(@issue_params)
|
||||
# 更改负责人
|
||||
if @issue.previous_changes["assigned_to_id"].present?
|
||||
journal = @issue.journals.create!({user_id: current_user.id, operate_by: "Issue"})
|
||||
journal.journal_details.create!({property: "reviewer", prop_key: 1, old_value: @issue.previous_changes["assigned_to_id"][0], value: @issue.previous_changes["assigned_to_id"][1]})
|
||||
end
|
||||
# 更改标题
|
||||
if @issue.previous_changes["subject"].present?
|
||||
journal = @issue.journals.create!({user_id: current_user.id, operate_by: "Issue"})
|
||||
journal.journal_details.create!({property: "attr", prop_key: "subject", old_value: @issue.previous_changes["subject"][0], value: @issue.previous_changes["subject"][1]})
|
||||
end
|
||||
|
||||
# 更改描述
|
||||
if @issue.previous_changes["description"].present?
|
||||
journal = @issue.journals.create!({user_id: current_user.id, operate_by: 'Issue'})
|
||||
journal.journal_details.create!({property: "attr", prop_key: "description", old_value: @issue.previous_changes["description"][0], value: @issue.previous_changes["description"][1]})
|
||||
end
|
||||
|
||||
# 修改优先级
|
||||
if @issue.previous_changes["priority_id"].present?
|
||||
journal = @issue.journals.create!({user_id: current_user.id, operate_by: 'Issue'})
|
||||
journal.journal_details.create!({property: "attr", prop_key: "priority_id", old_value: @issue.previous_changes["priority_id"][0], value: @issue.previous_changes["priority_id"][1]})
|
||||
end
|
||||
|
||||
# 修改里程碑
|
||||
if @issue.previous_changes["fixed_version_id"].present?
|
||||
journal = @issue.journals.create!({user_id: current_user.id, operate_by: 'Issue'})
|
||||
journal.journal_details.create!({property: "attr", prop_key: "fixed_version_id", old_value: @issue.previous_changes["fixed_version_id"][0], value: @issue.previous_changes["fixed_version_id"][1]})
|
||||
end
|
||||
|
||||
if @pull_request.update_attributes(@local_params.compact)
|
||||
gitea_pull = Gitea::PullRequest::UpdateService.call(@owner.login, @repository.identifier,
|
||||
@pull_request.gitea_number, @requests_params, current_user.gitea_token)
|
||||
|
||||
if gitea_pull[:status] === :success
|
||||
if params[:issue_tag_ids].present?
|
||||
if params[:issue_tag_ids].is_a?(Array) && params[:issue_tag_ids].size > 1
|
||||
return normal_status(-1, "最多只能创建一个标记。")
|
||||
elsif params[:issue_tag_ids].is_a?(Array) && params[:issue_tag_ids].size == 1
|
||||
#if params[:issue_tag_ids].present?
|
||||
#if params[:issue_tag_ids].is_a?(Array) && params[:issue_tag_ids].size > 1
|
||||
# return normal_status(-1, "最多只能创建一个标记。")
|
||||
#elsif params[:issue_tag_ids].is_a?(Array) && params[:issue_tag_ids].size == 1
|
||||
if params[:issue_tag_ids].is_a?(Array) #&& params[:issue_tag_ids].present?
|
||||
new_issue_tag_ids = params[:issue_tag_ids].sort!
|
||||
now_issue_tag_ids = @issue.issue_tags.pluck(:id).sort!
|
||||
if (!(now_issue_tag_ids & new_issue_tag_ids).empty? || !(now_issue_tag_ids.empty? && new_issue_tag_ids.empty?)) && new_issue_tag_ids != now_issue_tag_ids
|
||||
journal = @issue.journals.create!({user_id: current_user.id, operate_by: 'Issue'})
|
||||
journal.journal_details.create!({property: "issue_tag", prop_key: "#{new_issue_tag_ids.size}", old_value: now_issue_tag_ids.join(","), value: new_issue_tag_ids.join(",")})
|
||||
end
|
||||
@issue&.issue_tags_relates&.destroy_all
|
||||
params[:issue_tag_ids].each do |tag|
|
||||
IssueTagsRelate.create!(issue_id: @issue.id, issue_tag_id: tag)
|
||||
|
|
@ -127,18 +165,22 @@ class PullRequestsController < ApplicationController
|
|||
else
|
||||
return normal_status(-1, "请输入正确的标记。")
|
||||
end
|
||||
end
|
||||
if params[:attached_issue_ids].present?
|
||||
if params[:attached_issue_ids].is_a?(Array) && params[:attached_issue_ids].size > 1
|
||||
return normal_status(-1, "最多只能关联一个疑修。")
|
||||
elsif params[:attached_issue_ids].is_a?(Array) && params[:attached_issue_ids].size == 1
|
||||
@pull_request&.pull_attached_issues&.destroy_all
|
||||
params[:attached_issue_ids].each do |issue|
|
||||
PullAttachedIssue.create!(issue_id: issue, pull_request_id: @pull_request.id)
|
||||
end
|
||||
else
|
||||
return normal_status(-1, "请输入正确的疑修。")
|
||||
#end
|
||||
if params[:attached_issue_ids].is_a?(Array) && params[:attached_issue_ids].size > 1
|
||||
return normal_status(-1, "最多只能关联一个疑修。")
|
||||
elsif params[:attached_issue_ids].is_a?(Array) #&& params[:attached_issue_ids].size == 1
|
||||
new_attached_issue_ids = params[:attached_issue_ids].sort!
|
||||
now_attached_issue_ids = @pull_request.attached_issues.pluck(:id).sort!
|
||||
if (!(now_attached_issue_ids & new_attached_issue_ids).empty? || !(now_attached_issue_ids.empty? && new_attached_issue_ids.empty?)) && new_attached_issue_ids != now_attached_issue_ids
|
||||
journal = @issue.journals.create!({user_id: current_user.id, operate_by: 'Issue'})
|
||||
journal.journal_details.create!({property: "attached_issue", prop_key: "#{new_attached_issue_ids.size}", old_value: now_attached_issue_ids.join(","), value: new_attached_issue_ids.join(",")})
|
||||
end
|
||||
@pull_request&.pull_attached_issues&.destroy_all
|
||||
params[:attached_issue_ids].each do |issue|
|
||||
PullAttachedIssue.create!(issue_id: issue, pull_request_id: @pull_request.id)
|
||||
end
|
||||
else
|
||||
return normal_status(-1, "请输入正确的疑修。")
|
||||
end
|
||||
if params[:status_id].to_i == 5
|
||||
@issue.issue_times.update_all(end_time: Time.now)
|
||||
|
|
@ -176,7 +218,11 @@ class PullRequestsController < ApplicationController
|
|||
@pull_request.project_trends.create!(user: current_user, project: @project,action_type: ProjectTrend::CLOSE)
|
||||
# 合并请求下issue处理为关闭
|
||||
@issue&.update_attributes!({status_id:5})
|
||||
# 修改状态
|
||||
journal = @issue.journals.create!({user_id: current_user.id, operate_by: 'Issue'})
|
||||
journal.journal_details.create!({property: "attr", prop_key: "status", old_value: 0, value: 2})
|
||||
SendTemplateMessageJob.perform_later('PullRequestClosed', current_user.id, @pull_request.id) if Site.has_notice_menu?
|
||||
ProjectActions::PullRequestEvent.build(@project, current_user, @pull_request, "closed")
|
||||
normal_status(1, "已拒绝")
|
||||
else
|
||||
normal_status(-1, '合并失败')
|
||||
|
|
@ -222,8 +268,10 @@ class PullRequestsController < ApplicationController
|
|||
if success_condition && @pull_request.merge!
|
||||
# @pull_request.project_trend_status!
|
||||
@pull_request.project_trends.create!(user: current_user, project: @project,action_type: ProjectTrend::MERGE)
|
||||
@issue&.custom_journal_detail("merge", "", "该合并请求已被合并", current_user&.id)
|
||||
|
||||
# @issue&.custom_journal_detail("merge", "", "该合并请求已被合并", current_user&.id)
|
||||
# 修改状态
|
||||
journal = @issue.journals.create!({user_id: current_user.id, operate_by: 'Issue'})
|
||||
journal.journal_details.create!({property: "attr", prop_key: "status", old_value: 0, value: 1})
|
||||
# author: zxh
|
||||
# 调用上链API
|
||||
push_activity_2_blockchain("pull_request_merge", @pull_request) if Site.has_blockchain? && @project.use_blockchain
|
||||
|
|
@ -247,6 +295,7 @@ class PullRequestsController < ApplicationController
|
|||
|
||||
# 合并请求下issue处理为关闭
|
||||
@issue&.update_attributes!({status_id:5})
|
||||
ProjectActions::PullRequestEvent.build(@project, current_user, @pull_request, "closed")
|
||||
SendTemplateMessageJob.perform_later('PullRequestMerged', current_user.id, @pull_request.id) if Site.has_notice_menu?
|
||||
normal_status(1, "合并成功")
|
||||
else
|
||||
|
|
@ -324,7 +373,7 @@ class PullRequestsController < ApplicationController
|
|||
# milestone: 0, #里程碑,未与本地的里程碑关联
|
||||
}
|
||||
assignee_login = User.find_by_id(params[:assigned_to_id])&.login
|
||||
@requests_params = @local_params.merge({assignees: [assignee_login.to_s].reject!(&:empty?)})
|
||||
@requests_params = @local_params.merge({assignees: [assignee_login.to_s].reject{|item|item.empty?}})
|
||||
@issue_params = {
|
||||
author_id: current_user.id,
|
||||
project_id: @project.id,
|
||||
|
|
|
|||
|
|
@ -83,8 +83,8 @@ class RepositoriesController < ApplicationController
|
|||
end
|
||||
|
||||
def sub_entries
|
||||
file_path_uri = URI.parse(URI.encode(params[:filepath].to_s.strip))
|
||||
|
||||
file_path_uri = URI.parse(URI.encode(params[:filepath].to_s))
|
||||
tip_exception('不可访问') if params[:filepath].to_s.include?("chinese_dictionary.txt")
|
||||
if @project.educoder?
|
||||
if params[:type] === 'file'
|
||||
@sub_entries = Educoder::Repository::Entries::GetService.call(@project&.project_educoder&.repo_name, file_path_uri)
|
||||
|
|
@ -294,7 +294,7 @@ class RepositoriesController < ApplicationController
|
|||
def archive
|
||||
domain = GiteaService.gitea_config[:domain]
|
||||
api_url = GiteaService.gitea_config[:base_url]
|
||||
archive_url = "/repos/#{@owner.login}/#{@repository.identifier}/archive/#{Addressable::URI.escape(params[:archive])}"
|
||||
archive_url = "/repos/#{@owner.login}/#{@repository.identifier}/archive/#{URI.encode(params[:archive])}"
|
||||
|
||||
file_path = [domain, api_url, archive_url].join
|
||||
file_path = [file_path, "access_token=#{@owner&.gitea_token}"].join("?")
|
||||
|
|
@ -307,6 +307,7 @@ class RepositoriesController < ApplicationController
|
|||
def raw
|
||||
domain = GiteaService.gitea_config[:domain]
|
||||
api_url = GiteaService.gitea_config[:base_url]
|
||||
tip_exception('不可访问') if params[:filepath].to_s.include?("chinese_dictionary.txt")
|
||||
|
||||
url = "/repos/#{@owner.login}/#{@repository.identifier}/raw/#{CGI.escape(params[:filepath])}?ref=#{CGI.escape(params[:ref])}"
|
||||
file_path = [domain, api_url, url].join
|
||||
|
|
@ -336,7 +337,7 @@ class RepositoriesController < ApplicationController
|
|||
# TODO 获取最新commit信息
|
||||
def project_commits
|
||||
if params[:filepath].present?
|
||||
file_path_uri = URI.parse(URI.encode(params[:filepath].to_s.strip))
|
||||
file_path_uri = URI.parse(URI.encode(params[:filepath].to_s))
|
||||
Gitea::Repository::Commits::FileListService.new(@project.owner.login, @project.identifier, file_path_uri,
|
||||
sha: get_ref, page: 1, limit: 1, token: @project&.owner&.gitea_token).call
|
||||
else
|
||||
|
|
@ -367,6 +368,7 @@ class RepositoriesController < ApplicationController
|
|||
|
||||
def content_params
|
||||
{
|
||||
base64_filepath: params[:base64_filepath],
|
||||
filepath: params[:filepath],
|
||||
branch: params[:branch],
|
||||
new_branch: params[:new_branch],
|
||||
|
|
|
|||
|
|
@ -89,6 +89,11 @@ class SettingsController < ApplicationController
|
|||
|
||||
def get_third_party_new
|
||||
@third_party_new = []
|
||||
@third_party_new << {
|
||||
name: 'ccf',
|
||||
url: "/oauth_ccf",
|
||||
method: 'get'
|
||||
}
|
||||
@third_party_new << {
|
||||
name: 'educoder',
|
||||
url: EducoderOauth.oauth_url,
|
||||
|
|
@ -96,13 +101,18 @@ class SettingsController < ApplicationController
|
|||
}
|
||||
platform_url = Rails.application.config_for(:configuration)['platform_url']
|
||||
config = Rails.application.config_for(:configuration)
|
||||
(config.dig("oauth").keys - ["educoder", "wechat"]).each do |provider|
|
||||
(config.dig("oauth").keys - ["educoder", "wechat", "ccf","openi"]).each do |provider|
|
||||
@third_party_new << {
|
||||
name: provider,
|
||||
url: "#{platform_url}/auth/#{provider}",
|
||||
method: 'get'
|
||||
}
|
||||
end
|
||||
@third_party_new << {
|
||||
name: 'openi',
|
||||
url: OpeniOauth.oauth_url,
|
||||
method: 'get'
|
||||
}
|
||||
end
|
||||
|
||||
def get_top_system_notification
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ class Users::OrganizationsController < Users::BaseController
|
|||
@organizations = observed_user.organizations.with_visibility("common")
|
||||
end
|
||||
|
||||
@organizations = @organizations.ransack(login_cont: params[:search]).result if params[:search].present?
|
||||
@organizations = @organizations.ransack(login_or_nickname_cont: params[:search]).result if params[:search].present?
|
||||
|
||||
@home_top_ids = @organizations.joins(:home_top_settings).where(home_top_settings: {user_id: observed_user.id}).order("home_top_settings.created_at asc").pluck(:id)
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ class UsersController < ApplicationController
|
|||
before_action :load_user, only: [:show, :homepage_info, :sync_token, :sync_gitea_pwd, :projects, :watch_users, :fan_users, :hovercard, :hovercard4proj]
|
||||
before_action :check_user_exist, only: [:show, :homepage_info,:projects, :watch_users, :fan_users, :hovercard, :hovercard4proj]
|
||||
before_action :require_login, only: %i[me sync_user_info]
|
||||
before_action :connect_to_ci_db, only: [:get_user_info]
|
||||
# before_action :connect_to_ci_db, only: [:get_user_info]
|
||||
before_action :convert_image!, only: [:update, :update_image]
|
||||
skip_before_action :check_sign, only: [:attachment_show]
|
||||
before_action :sso_login, only: [:get_user_info]
|
||||
|
|
@ -50,6 +50,7 @@ class UsersController < ApplicationController
|
|||
org_projects = Project.joins(team_projects: [team: :team_users]).where(team_users: {user_id: @user.id}).to_sql
|
||||
projects = Project.from("( #{ normal_projects} UNION #{ org_projects } ) AS projects").distinct
|
||||
user_projects = User.current.logged? && (User.current.admin? || User.current.login == @user.login) ? projects : projects.visible
|
||||
@user_projects_count = user_projects.size
|
||||
@projects_common_count = user_projects.common.size
|
||||
@projects_mirrior_count = user_projects.mirror.size
|
||||
@projects_sync_mirrior_count = user_projects.sync_mirror.size
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ class VersionReleasesController < ApplicationController
|
|||
if params[:attachment_ids].present?
|
||||
create_attachments(params[:attachment_ids], version_release)
|
||||
end
|
||||
ProjectActions::ReleaseEvent.build(@project, current_user, version_release)
|
||||
normal_status(0, "发布成功")
|
||||
else
|
||||
normal_status(-1, "发布失败")
|
||||
|
|
|
|||
|
|
@ -27,6 +27,9 @@ class WatchersController < ApplicationController
|
|||
def follow
|
||||
begin
|
||||
return normal_status(2, "你已关注了") if current_user.watched?(@target)
|
||||
if @target.is_a?(Project)
|
||||
ProjectActions::StarEvent.build(@target, current_user)
|
||||
end
|
||||
current_user.watch!(@target)
|
||||
render_ok({watchers_count: @target.watchers_count, watched: true})
|
||||
rescue Exception => e
|
||||
|
|
|
|||
|
|
@ -157,6 +157,12 @@ module ApplicationHelper
|
|||
end
|
||||
end
|
||||
|
||||
def customized_img(project_id)
|
||||
icons = Array.new(43) { |i| "icon_#{i + 1}.png" }
|
||||
index = project_id % icons.size
|
||||
File.join("images/NSCCN", "","#{index}.png")
|
||||
end
|
||||
|
||||
def url_to_avatar_with_platform_url(source)
|
||||
platform_url = Rails.application.config_for(:configuration)['platform_url']
|
||||
if platform_url
|
||||
|
|
|
|||
|
|
@ -14,15 +14,15 @@ module ProjectsHelper
|
|||
end
|
||||
|
||||
def render_zip_url(owner, repository, archive)
|
||||
[base_url, archive_repositories_path(owner&.login, repository, "#{archive}.zip")].join
|
||||
[base_url, archive_repositories_path(owner&.login, repository.identifier, "#{archive}.zip")].join
|
||||
end
|
||||
|
||||
def render_tar_url(owner, repository, archive)
|
||||
[base_url, archive_repositories_path(owner&.login, repository, "#{archive}.tar.gz")].join
|
||||
[base_url, archive_repositories_path(owner&.login, repository.identifier, "#{archive}.tar.gz")].join
|
||||
end
|
||||
|
||||
def render_download_file_url(owner, repository, filepath, ref)
|
||||
[base_url, "/api/#{owner&.login}/#{repository.identifier}/raw/#{CGI.escape(filepath)}?ref=#{CGI.escape(ref)}"].join
|
||||
[base_url, "/api/#{owner&.login}/#{repository.identifier}/raw/#{URI.escape(filepath)}?ref=#{CGI.escape(ref)}"].join
|
||||
end
|
||||
|
||||
def render_http_url(project)
|
||||
|
|
@ -84,9 +84,10 @@ module ProjectsHelper
|
|||
image_url: project.project_educoder.image_url
|
||||
}
|
||||
else
|
||||
name = project.repository&.mirror_url.present? ? project.repository&.mirror_url.split('/')[-2] : project.owner.real_name
|
||||
{
|
||||
login: @owner.login,
|
||||
name: @owner.real_name,
|
||||
name: @owner.login == "NSCCN" ? name : @owner.real_name,
|
||||
type: @owner.type,
|
||||
image_url: url_to_avatar(@owner)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -157,10 +157,12 @@ module RepositoriesHelper
|
|||
next if s_content.starts_with?('http://') || s_content.starts_with?('https://') || s_content.starts_with?('mailto:') || s_content.blank?
|
||||
ext = File.extname(s_content)[1..-1]
|
||||
ext = ext.split("?")[0] if ext.include?("?")
|
||||
ext = ext.gsub(/ \".*\"/, "") if ext.include?(" ")
|
||||
if (image_type?(ext) || download_type(ext)) && !ext.blank?
|
||||
s_content = s_content.starts_with?("/") ? s_content[1..-1] : s_content[0..-1]
|
||||
s_content = File.expand_path(s_content, file_path)
|
||||
s_content = s_content.split("#{Rails.root}/")[1]
|
||||
s_content = s_content.gsub(/ \".*\"/, "") if s_content.include?(" ")
|
||||
next if s_content.blank?
|
||||
# content = content.gsub(s[0], "/#{s_content}")
|
||||
join_xxx = s_content.include?("?") ? "&" : "?"
|
||||
|
|
@ -184,8 +186,16 @@ module RepositoriesHelper
|
|||
content = content.gsub("href=\"#{s[0]}\"", "href=\"#{s_content}\"")
|
||||
when 'ss_href_1'
|
||||
content = content.gsub("href=\'#{s[0]}\'", "href=\'#{s_content}\'")
|
||||
else
|
||||
content = content.gsub("(#{s[0]})", "(#{s_content})")
|
||||
else
|
||||
## md中图片处理包含中文名称,tip
|
||||
if s[0].to_s.include?(" ")
|
||||
s1 = s[0].to_s.split(" ")
|
||||
str1 = s1[0]
|
||||
str2 = s1[1] if s1.size >1
|
||||
content = content.gsub("(#{str1} #{str2})", "(#{s_content} #{str2})")
|
||||
else
|
||||
content = content.gsub("(#{s[0]})", "(#{s_content})")
|
||||
end
|
||||
end
|
||||
else
|
||||
path = [owner&.login, repo&.identifier, 'tree', ref, file_path].join("/")
|
||||
|
|
@ -203,7 +213,7 @@ module RepositoriesHelper
|
|||
content = content.gsub("href=\"#{s[0]}\"", "href=\"#{s_content}\"")
|
||||
when 'ss_href_1'
|
||||
content = content.gsub("href=\'#{s[0]}\'", "href=\'#{s_content}\'")
|
||||
else
|
||||
else
|
||||
content = content.gsub("(#{s[0]})", "(#{s_content})")
|
||||
end
|
||||
end
|
||||
|
|
@ -244,7 +254,9 @@ module RepositoriesHelper
|
|||
Rails.logger.info("entry===#{entry["type"]} #{entry["name"]}")
|
||||
content = entry['content'].present? ? entry['content'] : Gitea::Repository::Entries::GetService.call(owner, repo.identifier, URI.escape(entry['path']), ref: ref)['content']
|
||||
# readme_render_decode64_content(content, owner, repo, ref)
|
||||
new_readme_render_decode64_content(content, owner, repo, ref, entry['path'], entry['name'])
|
||||
text = new_readme_render_decode64_content(content, owner, repo, ref, entry['path'], entry['name'])
|
||||
# text = "该内容不合规,请修改。" if text.present? && !HarmoniousDictionary.clean?(text)
|
||||
text
|
||||
end
|
||||
|
||||
def decode64_content(entry, owner, repo, ref, path=nil)
|
||||
|
|
@ -253,9 +265,13 @@ module RepositoriesHelper
|
|||
content = entry['content'].present? ? entry['content'] : Gitea::Repository::Entries::GetService.call(owner, repo.identifier, URI.escape(entry['path']), ref: ref)['content']
|
||||
# Rails.logger.info("content===#{content}")
|
||||
return Base64.decode64(content).force_encoding("GBK").encode("UTF-8") unless Base64.decode64(content).force_encoding('UTF-8').valid_encoding?
|
||||
return Base64.decode64(content).force_encoding('UTF-8')
|
||||
text = Base64.decode64(content).force_encoding('UTF-8')
|
||||
# text = "该内容不合规,请修改。" if text.present? && !HarmoniousDictionary.clean?(text)
|
||||
text
|
||||
elsif entry['is_text_file'] == true
|
||||
return render_decode64_content(entry['content'])
|
||||
text = render_decode64_content(entry['content'])
|
||||
# text = "该内容不合规,请修改。" if text.present? && !HarmoniousDictionary.clean?(text)
|
||||
text
|
||||
else
|
||||
file_type = File.extname(entry['name'].to_s)[1..-1]
|
||||
if image_type?(file_type)
|
||||
|
|
@ -264,7 +280,9 @@ module RepositoriesHelper
|
|||
if download_type(file_type)
|
||||
return entry['content']
|
||||
end
|
||||
render_decode64_content(entry['content'])
|
||||
text = render_decode64_content(entry['content'])
|
||||
# text = "该内容不合规,请修改。" if text.present? && !HarmoniousDictionary.clean?(text)
|
||||
text
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -305,7 +323,13 @@ module RepositoriesHelper
|
|||
|
||||
def repo_git_submodule_url(owner, repo, path)
|
||||
unless (path.starts_with?('http://') || path.starts_with?('https://'))
|
||||
path = File.expand_path(path, "/#{owner&.login}/#{repo&.identifier}")
|
||||
if path.starts_with?('git@code.gitlink.org.cn')
|
||||
path = path.gsub(":","/").gsub("git@code.gitlink.org.cn","https://gitlink.org.cn")
|
||||
elsif path.starts_with?('git@code.gitlink.org.cn')
|
||||
path = path.gsub(":","/").gsub("git@","https://")
|
||||
else
|
||||
path = File.expand_path(path, "/#{owner&.login}/#{repo&.identifier}")
|
||||
end
|
||||
end
|
||||
|
||||
return path
|
||||
|
|
|
|||
|
|
@ -56,6 +56,8 @@ module Gitea
|
|||
else
|
||||
@params[:filepath]
|
||||
end
|
||||
rescue
|
||||
@params[:filepath]
|
||||
end
|
||||
|
||||
def valid_params
|
||||
|
|
@ -73,6 +75,7 @@ module Gitea
|
|||
file_params = file_params.merge(content: @params[:content] || "")
|
||||
file_params = file_params.merge(message: @params[:message]) unless @params[:message].blank?
|
||||
file_params = file_params.merge(committer: @params[:committer])
|
||||
file_params = file_params.merge(dates: {"author": Time.now, "committer": Time.now})
|
||||
file_params
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -51,10 +51,12 @@ module Gitea
|
|||
|
||||
def file_path
|
||||
if @params[:base64_filepath].present?
|
||||
Base64.decode64(params[:base64_filepath])
|
||||
Base64.strict_decode64(params[:base64_filepath])
|
||||
else
|
||||
@params[:filepath]
|
||||
end
|
||||
rescue
|
||||
@params[:filepath]
|
||||
end
|
||||
|
||||
def valid_params
|
||||
|
|
@ -70,6 +72,7 @@ module Gitea
|
|||
sha: @params[:sha],
|
||||
new_branch: @params[:new_branch],
|
||||
message: @params[:message],
|
||||
dates: {"author": Time.now, "committer": Time.now}
|
||||
).compact
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -50,18 +50,22 @@ module Gitea
|
|||
|
||||
def file_path
|
||||
if @params[:base64_filepath].present?
|
||||
Base64.decode64(params[:base64_filepath])
|
||||
Base64.strict_decode64(params[:base64_filepath])
|
||||
else
|
||||
@params[:filepath]
|
||||
end
|
||||
rescue
|
||||
@params[:filepath]
|
||||
end
|
||||
|
||||
def from_file_path
|
||||
if @params[:base64_from_path].present?
|
||||
Base64.decode64(params[:base64_from_path])
|
||||
Base64.strict_decode64(params[:base64_from_path])
|
||||
else
|
||||
@params[:from_path]
|
||||
end
|
||||
rescue
|
||||
@params[:from_path]
|
||||
end
|
||||
|
||||
def valid_params
|
||||
|
|
@ -80,7 +84,8 @@ module Gitea
|
|||
new_branch: @params[:new_branch],
|
||||
from_path: from_file_path,
|
||||
message: @params[:message],
|
||||
content: Base64.encode64(@params[:content])
|
||||
content: Base64.encode64(@params[:content]),
|
||||
dates: {"author": Time.now, "committer": Time.now}
|
||||
).compact
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ class OpenProjectDevOpsJob < ApplicationJob
|
|||
return if project.blank?
|
||||
return if EduSetting.get("jianmu_devops_url").blank?
|
||||
user = User.find_by(id: user_id)
|
||||
return if user.blank?
|
||||
code = jianmu_devops_code(project, user)
|
||||
uri = URI.parse("#{jianmu_devops_url}/activate?code=#{URI.encode_www_form_component(code)}")
|
||||
response = Net::HTTP.get_response(uri)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,54 @@
|
|||
require 'oauth2'
|
||||
|
||||
module Ccf::Service
|
||||
module_function
|
||||
|
||||
def client_id
|
||||
config = Rails.application.config_for(:configuration)
|
||||
config.dig("oauth", "ccf", "client_id")
|
||||
end
|
||||
|
||||
def client_secret
|
||||
config = Rails.application.config_for(:configuration)
|
||||
config.dig("oauth", "ccf", "client_secret")
|
||||
end
|
||||
|
||||
def base_url
|
||||
config = Rails.application.config_for(:configuration)
|
||||
config.dig("oauth", "ccf", "base_url")
|
||||
end
|
||||
|
||||
def redirect_uri
|
||||
config = Rails.application.config_for(:configuration)
|
||||
config.dig("oauth", "ccf", "redirect_uri")
|
||||
end
|
||||
|
||||
def oauth_url
|
||||
"#{base_url}/auth?appid=GitLink&from=#{Base64.strict_encode64(redirect_uri)}&source=42Rb6s"
|
||||
end
|
||||
|
||||
def access_token(code)
|
||||
begin
|
||||
Rails.logger.info("[CcfOauth] [code] #{code} ")
|
||||
Rails.logger.info("[CcfOauth] [redirect_uri] #{redirect_uri} ")
|
||||
client = OAuth2::Client.new(client_id, client_secret, site: base_url)
|
||||
result = client.auth_code.get_token(code, redirect_uri: redirect_uri).to_hash
|
||||
return result
|
||||
rescue Exception => e
|
||||
raise Gitlink::TipException.new(e.message)
|
||||
end
|
||||
end
|
||||
|
||||
def user_info(access_token)
|
||||
url = "#{base_url}/api/v1/json/auth_info"
|
||||
auth_json = { "appid": "GitLink", "code": access_token, "scope": "user_info" }
|
||||
uri = URI.parse(url)
|
||||
http = Net::HTTP.new(uri.hostname, uri.port)
|
||||
if url.include?("https://")
|
||||
http.use_ssl = true
|
||||
end
|
||||
response = http.send_request('POST', uri.path, auth_json.to_json, {'Content-Type' => 'application/json'})
|
||||
Rails.logger.info("#######_________CcfOauth user_info_____#########{response.body}")
|
||||
JSON.parse(response.body)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
module OpeniOauth
|
||||
class << self
|
||||
attr_accessor :client_id, :client_secret, :base_url, :redirect_uri
|
||||
|
||||
def logger
|
||||
@_logger ||= STDOUT
|
||||
end
|
||||
|
||||
def logger=(l)
|
||||
@_logger = l
|
||||
end
|
||||
|
||||
def oauth_url
|
||||
"#{base_url}/login/oauth/authorize?client_id=#{client_id}&redirect_uri=#{URI.encode_www_form_component(redirect_uri)}&response_type=code"
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
require 'oauth2'
|
||||
|
||||
module OpeniOauth::Service
|
||||
module_function
|
||||
|
||||
def request(method, url, params)
|
||||
begin
|
||||
Rails.logger.info("[OpeniOauth] [#{method.to_s.upcase}] #{url} || #{params}")
|
||||
|
||||
client = Faraday.new(url: OpeniOauth.base_url)
|
||||
response = client.public_send(method, url, params)
|
||||
result = JSON.parse(response.body)
|
||||
|
||||
Rails.logger.info("[OpeniOauth] [#{response.status}] #{result}")
|
||||
|
||||
result
|
||||
rescue Exception => e
|
||||
raise Gitlink::TipException.new(e.message)
|
||||
end
|
||||
end
|
||||
|
||||
def access_token(code)
|
||||
begin
|
||||
Rails.logger.info("[OpeniOauth] [code] #{code} ")
|
||||
Rails.logger.info("[OpeniOauth] [redirect_uri] #{OpeniOauth.redirect_uri} ")
|
||||
client = OAuth2::Client.new(OpeniOauth.client_id, OpeniOauth.client_secret, site: OpeniOauth.base_url, token_url: "/login/oauth/access_token")
|
||||
result = client.auth_code.get_token(code, redirect_uri: OpeniOauth.redirect_uri)
|
||||
Rails.logger.info("[OpeniOauth] [get_token result] #{result}")
|
||||
return result.to_hash
|
||||
rescue Exception => e
|
||||
raise Gitlink::TipException.new(e.message)
|
||||
end
|
||||
end
|
||||
|
||||
def user_info(access_token)
|
||||
request(:get, '/api/v1/user', { access_token: access_token })
|
||||
end
|
||||
end
|
||||
|
|
@ -13,30 +13,31 @@ module SonarService
|
|||
|
||||
lines = []
|
||||
lines << "sonar.projectKey=#{owner}-#{project_id}"
|
||||
lines << "sonar.projectVersion=1.0"
|
||||
lines << "sonar.sourceEncoding=UTF-8"
|
||||
lines << "sonar.sources=."
|
||||
lines << "sonar.exclusions=**/test/**,**/tests/**,**/vendor/**,**/node_modules/**,**/__pycache__/**"
|
||||
lines << " sonar.projectVersion=1.0"
|
||||
lines << " sonar.sourceEncoding=UTF-8"
|
||||
lines << " sonar.sources=."
|
||||
lines << " sonar.exclusions=**/test/**,**/tests/**,**/vendor/**,**/node_modules/**,**/__pycache__/**"
|
||||
|
||||
if detected_langs.include?(:java)
|
||||
lines << "sonar.java.binaries="
|
||||
lines << " sonar.java.binaries=build_tmp_folder"
|
||||
lines << " sonar.language=java"
|
||||
end
|
||||
|
||||
if detected_langs.include?(:js)
|
||||
lines << "sonar.javascript.lcov.reportPaths=coverage/lcov.info"
|
||||
lines << " sonar.javascript.lcov.reportPaths=coverage/lcov.info"
|
||||
end
|
||||
|
||||
if detected_langs.include?(:ts)
|
||||
lines << "sonar.typescript.tsconfigPath=tsconfig.json"
|
||||
lines << " sonar.typescript.tsconfigPath=tsconfig.json"
|
||||
end
|
||||
|
||||
if detected_langs.include?(:python)
|
||||
lines << "sonar.python.coverage.reportPaths=coverage.xml"
|
||||
lines << " sonar.python.coverage.reportPaths=coverage.xml"
|
||||
end
|
||||
|
||||
if detected_langs.include?(:cpp)
|
||||
lines << "sonar.cxx.file.suffixes=.cpp,.c,.cc,.h,.hpp,.hh"
|
||||
lines << "sonar.cxx.errorRecoveryEnabled=true"
|
||||
lines << " sonar.cxx.file.suffixes=.cpp,.c,.cc,.h,.hpp,.hh"
|
||||
lines << " sonar.cxx.errorRecoveryEnabled=true"
|
||||
end
|
||||
|
||||
lines.join("\n")
|
||||
|
|
|
|||
|
|
@ -0,0 +1,89 @@
|
|||
module UserOnline
|
||||
class << self
|
||||
redis_config = YAML.load_file(Rails.root.join('config', 'redis.yml'))
|
||||
if redis_config.present?
|
||||
redis_url = redis_config[Rails.env]['url']
|
||||
$redis = Redis.new({:url=>redis_url})
|
||||
else
|
||||
$redis = Rails.cache.data
|
||||
end
|
||||
def login(user_id)
|
||||
set_bit(user_id, 1)
|
||||
end
|
||||
|
||||
def logout(user_id)
|
||||
if Rails.cache.is_a?(ActiveSupport::Cache::RedisStore)
|
||||
now = Time.now()
|
||||
keys = []
|
||||
(1..5).each do |i|
|
||||
key = (now - i.minutes).strftime("%H-%M")
|
||||
keys << "cache:online_user_#{key}"
|
||||
set_bit_and_expire(cache_key, user_id, 0) unless $redis.ttl(cache_key) == -2
|
||||
end
|
||||
end
|
||||
set_bit(user_id, 0)
|
||||
end
|
||||
|
||||
def set_bit(user_id, flag)
|
||||
if $redis.ttl(cache_key) == -2
|
||||
# 如果key不存在
|
||||
set_bit_and_expire(cache_key, user_id, flag)
|
||||
else
|
||||
if $redis.ttl(cache_key) ==-1
|
||||
# 可以存在,但过期时间没关联
|
||||
# 这种情况大概率是并发原因导致对相应key设置过期时跳过了。所以删除并重新设置过期时间
|
||||
$redis.del(cache_key)
|
||||
set_bit_and_expire(cache_key, user_id, flag)
|
||||
end
|
||||
|
||||
# 统计当前时间下,前5分钟的活跃人数
|
||||
$redis.setbit(cache_key, user_id, flag)
|
||||
end
|
||||
end
|
||||
|
||||
def set_bit_and_expire(cache_key, user_id, flag)
|
||||
$redis.setbit(cache_key, user_id, flag)
|
||||
# $redis.setbit(last_cache_key, user_id, flag)
|
||||
# 现在统计5分钟在线人数,这里设置6分钟过期,目的是统计当前时刻的前5分钟
|
||||
$redis.expire(cache_key, 6 * 60)
|
||||
end
|
||||
|
||||
def count
|
||||
if Rails.cache.is_a?(ActiveSupport::Cache::RedisStore)
|
||||
now = Time.now()
|
||||
keys = []
|
||||
(0..4).each do |i|
|
||||
key = (now - i.minutes).strftime("%H-%M")
|
||||
keys << "cache:online_user_#{key}"
|
||||
end
|
||||
# 防止每个分钟数据有重复,所以去重去除
|
||||
$redis.bitop("OR", "daiao", keys)
|
||||
$redis.bitcount("daiao")
|
||||
else
|
||||
0
|
||||
end
|
||||
end
|
||||
|
||||
def cache_key
|
||||
if Rails.cache.is_a?(ActiveSupport::Cache::RedisStore)
|
||||
"cache:online_user_#{Time.now().strftime("%H-%M")}"
|
||||
else
|
||||
raise '请配置config.cache_store = redis_store'
|
||||
end
|
||||
end
|
||||
|
||||
def last_cache_key
|
||||
if Rails.cache.is_a?(ActiveSupport::Cache::RedisStore)
|
||||
# 如设置5分钟内即300秒有请求的用户视为在线, 则最大会统计到10分钟内有活动用户
|
||||
# TODO 更精确时长
|
||||
begin_hour = Time.now.beginning_of_hour
|
||||
minutes_piece = (Time.now - begin_hour) / (60 * 5)
|
||||
time = begin_hour.since((minutes_piece.to_i - 1) * (60 * 5)).strftime("%H-%M")
|
||||
"cache:online_user_#{time}"
|
||||
else
|
||||
raise '请配置config.cache_store = redis_store'
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
@ -38,11 +38,12 @@ class Action::Node < ApplicationRecord
|
|||
|
||||
belongs_to :user, optional: true
|
||||
|
||||
attr_accessor :cust_name, :run_values, :input_values, :parent_node_id, :sub_nodes, :link_type_array, :node_id
|
||||
attr_accessor :cust_name, :run_values, :input_values, :env_input_values, :parent_node_id, :sub_nodes, :link_type_array, :node_id
|
||||
|
||||
validates :name, presence: { message: "不能为空" }
|
||||
|
||||
validates :name, presence: { message: "不能为空" }, uniqueness: true
|
||||
validates :full_name, length: { maximum: 200, too_long: "不能超过200个字符" }
|
||||
validates :label, length: { maximum: 200, too_long: "不能超过200个字符" }
|
||||
validates :label, length: { maximum: 200, too_long: "不能超过200个字符" }, uniqueness: true
|
||||
validates :description, length: { maximum: 65535, too_long: "不能超过65535个字符"}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
# content :text(65535)
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# remote_ip :string(255)
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
|
|
|
|||
|
|
@ -105,6 +105,24 @@ class Issue < ApplicationRecord
|
|||
scope :pm_includes, -> {includes(:project, :show_issue_tags, :issue_status, :priority, :version, :user, :show_assigners, :comment_journals, :operate_journals)}
|
||||
scope :closed, ->{where(status_id: 5)}
|
||||
scope :opened, ->{where.not(status_id: 5)}
|
||||
scope :with_assigner_info, -> {
|
||||
select("DISTINCT issues.*, u.id AS user_id, CONVERT(COALESCE(u.nickname, u.login) USING gbk) AS user_name").
|
||||
joins("LEFT JOIN (
|
||||
SELECT ia.issue_id, ia.assigner_id
|
||||
FROM issue_assigners ia
|
||||
JOIN (
|
||||
SELECT issue_id, MIN(id) AS min_assigner_id
|
||||
FROM issue_assigners
|
||||
GROUP BY issue_id
|
||||
) tmp ON ia.issue_id = tmp.issue_id AND ia.id = tmp.min_assigner_id
|
||||
) assigner ON issues.id = assigner.issue_id
|
||||
LEFT JOIN users u ON assigner.assigner_id = u.id")
|
||||
}
|
||||
|
||||
scope :ordered_by_assigner, -> (sort_direction) {
|
||||
order("CASE WHEN u.id IS NULL THEN 1 ELSE 0 END ASC")
|
||||
.order("CONVERT(COALESCE(u.nickname, u.login) USING gbk) #{sort_direction}")
|
||||
}
|
||||
after_create :incre_project_common, :incre_user_statistic, :incre_platform_statistic
|
||||
before_save :check_pm_and_update_due_date
|
||||
after_save :incre_or_decre_closed_issues_count, :change_versions_count, :send_update_message_to_notice_system, :associate_attachment_container, :generate_uuid
|
||||
|
|
@ -124,6 +142,20 @@ class Issue < ApplicationRecord
|
|||
end
|
||||
end
|
||||
|
||||
def pm_issue_type_chinese_string
|
||||
case pm_issue_type
|
||||
when 1
|
||||
"需求"
|
||||
when 2
|
||||
"任务"
|
||||
when 3
|
||||
"缺陷"
|
||||
else
|
||||
"疑修"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def destroy_be_pm_links
|
||||
PmLink.where(be_linkable_type:"Issue",be_linkable_id:self.id).map(&:destroy)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ class Journal < ApplicationRecord
|
|||
content += "<b>#{self.issue.subject}</b>"
|
||||
else
|
||||
prefix = '将'
|
||||
prefix += "计划" if self.issue.pm_issue_type == 1
|
||||
prefix += "需求" if self.issue.pm_issue_type == 1
|
||||
prefix += "任务" if self.issue.pm_issue_type == 2
|
||||
prefix += "缺陷" if self.issue.pm_issue_type == 3
|
||||
prefix += "<b>#{self.issue.subject}</b>"
|
||||
|
|
@ -358,9 +358,9 @@ class Journal < ApplicationRecord
|
|||
new_value = "未设置" if detail.value.blank?
|
||||
content += "将工作项类型由<b>#{old_value}</b>更改为<b>#{new_value}</b>"
|
||||
end
|
||||
content.gsub!('1', '需求')
|
||||
content.gsub!('2', '任务')
|
||||
content.gsub!('3', '缺陷')
|
||||
content.gsub!('<b>1</b>', '需求')
|
||||
content.gsub!('<b>2</b>', '任务')
|
||||
content.gsub!('<b>3</b>', '缺陷')
|
||||
return content
|
||||
when 'pm_sprint_id'
|
||||
old_value = detail.old_value
|
||||
|
|
@ -483,36 +483,30 @@ class Journal < ApplicationRecord
|
|||
end
|
||||
return content
|
||||
when 'link_issue'
|
||||
old_value = Issue.where(id: detail.old_value.to_s.split(",")).map{|i| "<b>[#{i.pm_issue_type}]-<#{i.subject}></b>"}.join("、")
|
||||
new_value = Issue.where(id: detail.value.to_s.split(",")).map{|i| "<b>[#{i.pm_issue_type}]-<#{i.subject}></b>"}.join("、")
|
||||
old_value = Issue.where(id: detail.old_value.to_s.split(",")).map{|i| i.pm_issue_type.nil? && i.pm_project_id.nil? ? "疑修 <b>【#{i.subject}】</b>" : "工作项 <b>[#{i.pm_issue_type_chinese_string}]-<#{i.subject}></b>"}.join("、")
|
||||
new_value = Issue.where(id: detail.value.to_s.split(",")).map{|i| i.pm_issue_type.nil? && i.pm_project_id.nil? ? "疑修 <b>【#{i.subject}】</b>" : "工作项 <b>[#{i.pm_issue_type_chinese_string}]-<#{i.subject}></b>"}.join("、")
|
||||
if detail.old_value.nil? || detail.old_value.blank?
|
||||
content += "新建了关联的工作项#{new_value}"
|
||||
content += "新建了关联的#{new_value}"
|
||||
else
|
||||
if detail.value.nil? || detail.value.blank?
|
||||
content += "删除了关联的工作项#{old_value}"
|
||||
content += "删除了关联的#{old_value}"
|
||||
else
|
||||
content += "新建了关联的工作项#{new_value}"
|
||||
content += "新建了关联的#{new_value}"
|
||||
end
|
||||
end
|
||||
content.gsub!('1', "需求")
|
||||
content.gsub!('2', "任务")
|
||||
content.gsub!('3', "缺陷")
|
||||
return content
|
||||
when 'tag_link_issue'
|
||||
old_value = Issue.where(id: detail.old_value.to_s.split(",")).map{|i| "<b>[#{i.pm_issue_type}]-<#{i.subject}></b>"}.join("、")
|
||||
new_value = Issue.where(id: detail.value.to_s.split(",")).map{|i| "<b>[#{i.pm_issue_type}]-<#{i.subject}></b>"}.join("、")
|
||||
old_value = Issue.where(id: detail.old_value.to_s.split(",")).map{|i| i.pm_issue_type.nil? && i.pm_project_id.nil? ? "疑修 <b>【#{i.subject}】</b>" : "工作项 <b>[#{i.pm_issue_type_chinese_string}]-<#{i.subject}></b>"}.join("、")
|
||||
new_value = Issue.where(id: detail.value.to_s.split(",")).map{|i| i.pm_issue_type.nil? && i.pm_project_id.nil? ? "疑修 <b>【#{i.subject}】</b>" : "工作项 <b>[#{i.pm_issue_type_chinese_string}]-<#{i.subject}></b>"}.join("、")
|
||||
if detail.old_value.nil? || detail.old_value.blank?
|
||||
content += "关联了工作项#{new_value}"
|
||||
content += "关联了#{new_value}"
|
||||
else
|
||||
if detail.value.nil? || detail.value.blank?
|
||||
content += "取消了关联的工作项#{old_value}"
|
||||
content += "取消了关联的#{old_value}"
|
||||
else
|
||||
content += "关联了工作项#{new_value}"
|
||||
content += "关联了#{new_value}"
|
||||
end
|
||||
end
|
||||
content.gsub!('1', "需求")
|
||||
content.gsub!('2', "任务")
|
||||
content.gsub!('3', "缺陷")
|
||||
return content
|
||||
when 'issue'
|
||||
issue = self.issue
|
||||
|
|
@ -535,6 +529,10 @@ class Journal < ApplicationRecord
|
|||
case detail.property
|
||||
when 'issue'
|
||||
content += "创建了<b>疑修</b>"
|
||||
return content
|
||||
when 'pull_request'
|
||||
content += "创建了<b>合并请求</b>"
|
||||
return content
|
||||
when 'attachment'
|
||||
old_value = Attachment.where("BINARY id in (?) or uuid in (?)", detail.old_value.to_s.split(","), detail.old_value.to_s.split(",")).pluck(:filename).join("、")
|
||||
new_value = Attachment.where("BINARY id in (?) or uuid in (?)", detail.value.to_s.split(","), detail.value.to_s.split(",")).pluck(:filename).join("、")
|
||||
|
|
@ -544,6 +542,7 @@ class Journal < ApplicationRecord
|
|||
new_value = "无" if new_value.blank?
|
||||
content += "将附件由<b>#{old_value}</b>更改为<b>#{new_value}</b>"
|
||||
end
|
||||
return content
|
||||
when 'issue_tag'
|
||||
old_value = IssueTag.where(id: detail.old_value.split(",")).pluck(:name).join("、")
|
||||
new_value = IssueTag.where(id: detail.value.split(",")).pluck(:name).join("、")
|
||||
|
|
@ -553,6 +552,17 @@ class Journal < ApplicationRecord
|
|||
new_value = "无" if new_value.blank?
|
||||
content += "将标记由<b>#{old_value}</b>更改为<b>#{new_value}</b>"
|
||||
end
|
||||
return content
|
||||
when 'attached_issue'
|
||||
old_value = Issue.where(id: detail.old_value.split(",")).pluck(:subject).join("、")
|
||||
new_value = Issue.where(id: detail.value.split(",")).pluck(:subject).join("、")
|
||||
if old_value.nil? || old_value.blank?
|
||||
content += "添加了<b>#{new_value}</b>关联疑修"
|
||||
else
|
||||
new_value = "无" if new_value.blank?
|
||||
content += "将关联疑修由<b>#{old_value}</b>更改为<b>#{new_value}</b>"
|
||||
end
|
||||
return content
|
||||
when 'assigner'
|
||||
old_value = User.where(id: detail.old_value.split(",")).map{|u| u.real_name}.join("、")
|
||||
new_value = User.where(id: detail.value.split(",")).map{|u| u.real_name}.join("、")
|
||||
|
|
@ -562,13 +572,38 @@ class Journal < ApplicationRecord
|
|||
new_value = "无" if new_value.blank?
|
||||
content += "将负责人由<b>#{old_value}</b>更改为<b>#{new_value}</b>"
|
||||
end
|
||||
return content
|
||||
when 'reviewer'
|
||||
old_value = User.find_by(id: detail.old_value)&.real_name
|
||||
new_value = User.find_by(id: detail.value)&.real_name
|
||||
if old_value.nil? || old_value.blank?
|
||||
content += "添加了审查人员<b>#{new_value}</b>"
|
||||
else
|
||||
new_value = "无" if new_value.blank?
|
||||
content += "将审查人员更改为<b>#{new_value}</b>"
|
||||
end
|
||||
return content
|
||||
when 'attr'
|
||||
content += "将"
|
||||
case detail.prop_key
|
||||
when 'subject'
|
||||
content += "修改了<b>标题</b>"
|
||||
content = "修改了<b>标题</b>"
|
||||
return content
|
||||
when 'description'
|
||||
content += "修改了<b>描述</b>"
|
||||
content = "修改了<b>描述</b>"
|
||||
return content
|
||||
when 'status'
|
||||
case detail.value.to_i
|
||||
when 0
|
||||
content = "<b>打开了</b>合并请求"
|
||||
when 1
|
||||
content = "<b>合并了</b>合并请求"
|
||||
when 2
|
||||
content = "<b>拒绝了</b>合并请求"
|
||||
when 4
|
||||
content = "<b>重新打开了</b>合并请求"
|
||||
end
|
||||
return content
|
||||
when 'status_id'
|
||||
old_value = IssueStatus.find_by_id(detail.old_value)&.name
|
||||
new_value = IssueStatus.find_by_id(detail.value)&.name
|
||||
|
|
@ -604,8 +639,9 @@ class Journal < ApplicationRecord
|
|||
new_value = "无" if new_value.blank?
|
||||
content += "由<b>#{old_value}</b>更改为<b>#{new_value}</b>"
|
||||
end
|
||||
return content
|
||||
end
|
||||
|
||||
content = self.pm_operate_content if content == ""
|
||||
end
|
||||
|
||||
def journal_content
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ class Laboratory < ApplicationRecord
|
|||
|
||||
validates :identifier, uniqueness: { case_sensitive: false }, allow_nil: true
|
||||
|
||||
delegate :name, :navbar, :footer, :login_logo_url, :nav_logo_url, :tab_logo_url, :default_navbar, to: :laboratory_setting
|
||||
delegate :name, :navbar, :footer, :login_logo_url, :nav_logo_url, :pm_logo_url, :tab_logo_url, :default_navbar, to: :laboratory_setting
|
||||
|
||||
def site
|
||||
rails_env = EduSetting.get('rails_env')
|
||||
|
|
|
|||
|
|
@ -34,7 +34,9 @@ class LaboratorySetting < ApplicationRecord
|
|||
def nav_logo_url
|
||||
image_url('nav')
|
||||
end
|
||||
|
||||
def pm_logo_url
|
||||
image_url('pm_logo')
|
||||
end
|
||||
def tab_logo_url
|
||||
image_url('tab')
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: open_users
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# user_id :integer
|
||||
# type :string(255)
|
||||
# uid :string(255)
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# extra :text(65535)
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_open_users_on_type_and_uid (type,uid) UNIQUE
|
||||
# index_open_users_on_user_id (user_id)
|
||||
#
|
||||
|
||||
class OpenUsers::Ccf < OpenUser
|
||||
def nickname
|
||||
extra&.[]('username')
|
||||
end
|
||||
|
||||
def en_type
|
||||
'ccf'
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: open_users
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# user_id :integer
|
||||
# type :string(255)
|
||||
# uid :string(255)
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# extra :text(65535)
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_open_users_on_type_and_uid (type,uid) UNIQUE
|
||||
# index_open_users_on_user_id (user_id)
|
||||
#
|
||||
|
||||
class OpenUsers::Openi < OpenUser
|
||||
def nickname
|
||||
extra&.[]('nickname')
|
||||
end
|
||||
|
||||
def en_type
|
||||
'openi'
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: project_actions
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# project_id :integer
|
||||
# type :string(255)
|
||||
# user_id :integer
|
||||
# event_extra :text(65535)
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_project_actions_on_project_id (project_id)
|
||||
#
|
||||
|
||||
class ProjectAction < ApplicationRecord
|
||||
|
||||
belongs_to :project
|
||||
belongs_to :user, optional: true
|
||||
|
||||
serialize :event_extra, Hash
|
||||
end
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: project_actions
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# project_id :integer
|
||||
# type :string(255)
|
||||
# user_id :integer
|
||||
# event_extra :text(65535)
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_project_actions_on_project_id (project_id)
|
||||
#
|
||||
|
||||
|
||||
class ProjectActions::ForkEvent < ProjectAction
|
||||
def self.build(project, user, fork_project)
|
||||
project_action = new(project: project, user: user)
|
||||
project_action.event_extra = {
|
||||
forkee_id: fork_project.id,
|
||||
forkee_name: fork_project.identifier,
|
||||
forkee_owner_id: fork_project.owner.id,
|
||||
forkee_owner_login: fork_project.owner.login
|
||||
}.as_json
|
||||
project_action.save!
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: project_actions
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# project_id :integer
|
||||
# type :string(255)
|
||||
# user_id :integer
|
||||
# event_extra :text(65535)
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_project_actions_on_project_id (project_id)
|
||||
#
|
||||
|
||||
|
||||
class ProjectActions::IssueCommentEvent < ProjectAction
|
||||
def self.build(project, user, issue, journal)
|
||||
project_action = new(project: project, user: user)
|
||||
project_action.event_extra = {
|
||||
issue_id: issue.id,
|
||||
issue_number: issue.project_issues_index,
|
||||
body: journal.notes
|
||||
}.as_json
|
||||
project_action.save!
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: project_actions
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# project_id :integer
|
||||
# type :string(255)
|
||||
# user_id :integer
|
||||
# event_extra :text(65535)
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_project_actions_on_project_id (project_id)
|
||||
#
|
||||
|
||||
|
||||
class ProjectActions::IssuesEvent < ProjectAction
|
||||
def self.build(project, user, issue, action)
|
||||
project_action = new(project: project, user: user)
|
||||
project_action.event_extra = {
|
||||
issue_id: issue.id,
|
||||
issue_number: issue.project_issues_index,
|
||||
issue_author_id: issue.author_id,
|
||||
issue_author_login: issue.user.login,
|
||||
title: issue.subject,
|
||||
body: issue.description,
|
||||
action: action
|
||||
}.as_json
|
||||
project_action.save!
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: project_actions
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# project_id :integer
|
||||
# type :string(255)
|
||||
# user_id :integer
|
||||
# event_extra :text(65535)
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_project_actions_on_project_id (project_id)
|
||||
#
|
||||
|
||||
|
||||
class ProjectActions::PullRequestEvent < ProjectAction
|
||||
def self.build(project, user, pull_request, action)
|
||||
project_action = new(project: project, user: user)
|
||||
gitea_pull_request = Gitea::PullRequest::FilesService.call(project.owner.login, project.identifier, pull_request.gitea_number, project&.owner&.gitea_token)
|
||||
project_action.event_extra = {
|
||||
action: action,
|
||||
pull_id: pull_request.id,
|
||||
pull_number: pull_request.gitea_number,
|
||||
title: pull_request.title,
|
||||
# body: pull_request.body,
|
||||
# git_diff: gitea_pull_request,
|
||||
additions: gitea_pull_request['TotalAddition'],
|
||||
deletions: gitea_pull_request['TotalDeletion'],
|
||||
changed_files: gitea_pull_request['NumFiles'],
|
||||
merged: pull_request.status == 1,
|
||||
base_ref: pull_request.base,
|
||||
head_repo_id: pull_request.is_original ? pull_request.fork_project_id : pull_request.project_id,
|
||||
head_repo_name: pull_request.project&.identifier,
|
||||
head_ref: pull_request.head
|
||||
}.as_json
|
||||
project_action.save!
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: project_actions
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# project_id :integer
|
||||
# type :string(255)
|
||||
# user_id :integer
|
||||
# event_extra :text(65535)
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_project_actions_on_project_id (project_id)
|
||||
#
|
||||
|
||||
|
||||
class ProjectActions::PullRequestReviewCommentEvent < ProjectAction
|
||||
def self.build(project, user, pull_request, journal)
|
||||
project_action = new(project: project, user: user)
|
||||
project_action.event_extra = {
|
||||
pull_id: pull_request.id,
|
||||
pull_number: pull_request.gitea_number,
|
||||
body: journal.notes
|
||||
}.as_json
|
||||
project_action.save!
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: project_actions
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# project_id :integer
|
||||
# type :string(255)
|
||||
# user_id :integer
|
||||
# event_extra :text(65535)
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_project_actions_on_project_id (project_id)
|
||||
#
|
||||
|
||||
|
||||
class ProjectActions::ReleaseEvent < ProjectAction
|
||||
def self.build(project, user, version_release)
|
||||
project_action = new(project: project, user: user)
|
||||
project_action.event_extra = {
|
||||
tag_name: version_release.tag_name,
|
||||
name: version_release.name,
|
||||
body: version_release.body
|
||||
}.as_json
|
||||
project_action.save!
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: project_actions
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# project_id :integer
|
||||
# type :string(255)
|
||||
# user_id :integer
|
||||
# event_extra :text(65535)
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_project_actions_on_project_id (project_id)
|
||||
#
|
||||
|
||||
class ProjectActions::StarEvent < ProjectAction
|
||||
def self.build(project, user)
|
||||
project_action = new(project: project, user: user)
|
||||
project_action.save!
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: project_templates
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# type :string(255)
|
||||
# project_id :integer
|
||||
# name :string(255)
|
||||
# content :text(65535)
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_project_templates_on_project_id (project_id)
|
||||
#
|
||||
|
||||
class ProjectTemplate < ApplicationRecord
|
||||
end
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: project_templates
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# type :string(255)
|
||||
# project_id :integer
|
||||
# name :string(255)
|
||||
# content :text(65535)
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_project_templates_on_project_id (project_id)
|
||||
#
|
||||
|
||||
class ProjectTemplates::Issue < ProjectTemplate
|
||||
|
||||
def self.init_data(project_id)
|
||||
if !self.exists?(project_id: project_id, name: "bug修复模板")
|
||||
self.create!(
|
||||
project_id: project_id,
|
||||
name: "bug修复模板",
|
||||
content: '## 问题描述
|
||||
[清晰简洁地描述Bug是什么]
|
||||
## 复现步骤
|
||||
1. [第一步]
|
||||
2. [第二步]
|
||||
3. [...]
|
||||
...
|
||||
## 期望行为
|
||||
[你期望发生什么]
|
||||
## 实际行为
|
||||
[实际发生了什么]
|
||||
## 环境信息
|
||||
- 操作系统:[如 macOS 12.3]
|
||||
- 浏览器/版本:[如 Chrome 101]
|
||||
- 项目版本/分支:[如 v1.2.0 或 main]
|
||||
## 附加信息
|
||||
[日志、截图、其他上下文]'
|
||||
)
|
||||
end
|
||||
if !self.exists?(project_id: project_id, name: "功能请求模板")
|
||||
|
||||
self.create!(
|
||||
project_id: project_id,
|
||||
name: "功能请求模板",
|
||||
content: '## 功能描述
|
||||
[你希望添加什么功能?为什么需要它?]
|
||||
## 解决方案
|
||||
[如果有,描述你希望的实现方式]
|
||||
## 替代方案
|
||||
[你考虑过的其他方案]
|
||||
## 影响范围
|
||||
[这个功能会影响哪些模块/用户?]
|
||||
## 补充说明
|
||||
[其他相关信息]'
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: project_templates
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# type :string(255)
|
||||
# project_id :integer
|
||||
# name :string(255)
|
||||
# content :text(65535)
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_project_templates_on_project_id (project_id)
|
||||
#
|
||||
|
||||
class ProjectTemplates::PullRequest < ProjectTemplate
|
||||
|
||||
def self.init_data(project_id)
|
||||
if !self.exists?(project_id: project_id, name: "bug修复模板")
|
||||
self.create!(
|
||||
project_id: project_id,
|
||||
name: "bug修复模板",
|
||||
content: '## 问题描述
|
||||
[清晰描述需要修复的问题,包括现象和影响]
|
||||
## 问题复现步骤
|
||||
1. [第一步]
|
||||
2. [第二步]
|
||||
3. [第三步]
|
||||
...
|
||||
## 根本原因
|
||||
[分析并描述导致问题的根本原因]
|
||||
## 修复方案
|
||||
[详细描述修复方法和实现逻辑]'
|
||||
)
|
||||
end
|
||||
if !self.exists?(project_id: project_id, name: "功能增强模板")
|
||||
self.create!(
|
||||
project_id: project_id,
|
||||
name: "功能增强模板",
|
||||
content: '## 合并请求描述
|
||||
[简要描述本次合并请求的目的和主要内容]
|
||||
## 相关Issue
|
||||
关联Issue编号:#{Issue编号}
|
||||
## 变更内容
|
||||
### 1. 增强了xxx'
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -22,7 +22,7 @@ class ProjectTrend < ApplicationRecord
|
|||
CREATE = 'create'
|
||||
MERGE = 'merge'
|
||||
|
||||
belongs_to :project
|
||||
belongs_to :project, optional: true
|
||||
belongs_to :trend, polymorphic: true, optional: true
|
||||
belongs_to :user
|
||||
end
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ class PullRequest < ApplicationRecord
|
|||
MERGED = 1
|
||||
CLOSED = 2
|
||||
NEEDCLA = 3
|
||||
REOPENED = 4
|
||||
|
||||
belongs_to :issue
|
||||
belongs_to :user
|
||||
|
|
@ -144,6 +145,18 @@ class PullRequest < ApplicationRecord
|
|||
"#{Rails.application.config_for(:configuration)['platform_url']}/#{self.project.owner.login}/#{self.project.name}/pulls/#{self.id}"
|
||||
end
|
||||
|
||||
def closed?
|
||||
self.status == CLOSED
|
||||
end
|
||||
|
||||
def merged?
|
||||
self.status == MERGED
|
||||
end
|
||||
|
||||
def opened?
|
||||
self.status == OPEN
|
||||
end
|
||||
|
||||
def pr_status
|
||||
case status
|
||||
when 0
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: sync_repositories
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# project_id :integer
|
||||
# type :string(255)
|
||||
# repo_name :string(255)
|
||||
# external_repo_address :string(255)
|
||||
# sync_granularity :integer
|
||||
# sync_direction :integer
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# external_token :string(255)
|
||||
# webhook_gid :integer
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_sync_repositories_on_project_id (project_id)
|
||||
#
|
||||
|
||||
class SyncRepositories::Osredm < SyncRepository
|
||||
end
|
||||
|
|
@ -1,19 +1,19 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: tokens
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# user_id :integer default("0"), not null
|
||||
# action :string(30) default(""), not null
|
||||
# value :string(40) default(""), not null
|
||||
# created_on :datetime not null
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_tokens_on_user_id (user_id)
|
||||
# tokens_value (value) UNIQUE
|
||||
#
|
||||
|
||||
# == Schema Information
|
||||
#
|
||||
# Table name: tokens
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# user_id :integer default("0"), not null
|
||||
# action :string(30) default(""), not null
|
||||
# value :string(40) default(""), not null
|
||||
# created_on :datetime not null
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_tokens_on_user_id (user_id)
|
||||
# tokens_value (value) UNIQUE
|
||||
#
|
||||
|
||||
|
||||
|
||||
#
|
||||
|
|
@ -50,7 +50,10 @@ class Token < ActiveRecord::Base
|
|||
token = Token.create(:user => user, :action => type)
|
||||
Rails.logger.info "###### Token.get_token_from_user is nul and agine create token: #{token&.value}"
|
||||
else
|
||||
token.update_attribute(:created_on, Time.now)
|
||||
unless Rails.cache.read("token::update::created_on::#{token.id}").present?
|
||||
token.update_attribute(:created_on, Time.now)
|
||||
Rails.cache.write("token::update::created_on::#{token.id}", true, expires_in: 5.minutes)
|
||||
end
|
||||
end
|
||||
token
|
||||
end
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ class User < Owner
|
|||
# trustie: 来自Trustie平台
|
||||
# forge: 平台本身注册的用户
|
||||
# military: 军科的用户
|
||||
enumerize :platform, in: [:forge, :educoder, :trustie, :military, :github, :gitee, :qq, :wechat, :bot, :acge], default: :forge, scope: :shallow
|
||||
enumerize :platform, in: [:forge, :educoder, :trustie, :military, :github, :gitee, :qq, :wechat, :bot, :acge, :ccf, :openi], default: :forge, scope: :shallow
|
||||
|
||||
belongs_to :laboratory, optional: true
|
||||
has_one :user_extension, dependent: :destroy
|
||||
|
|
@ -693,8 +693,9 @@ class User < Owner
|
|||
def self.try_to_autologin(key)
|
||||
user = Token.find_active_user('autologin', key)
|
||||
if user
|
||||
Rails.cache.fetch("user::update::last_login_on::#{user.id}",:expires_in => 5.minutes) do
|
||||
unless Rails.cache.read("user::update::last_login_on::#{user.id}").present?
|
||||
user.update(last_login_on: Time.now)
|
||||
Rails.cache.write("user::update::last_login_on::#{user.id}", true, expires_in: 5.minutes)
|
||||
end
|
||||
end
|
||||
user
|
||||
|
|
|
|||
|
|
@ -25,16 +25,20 @@
|
|||
|
||||
class UserAction < ApplicationRecord
|
||||
|
||||
belongs_to :user, optional: true
|
||||
|
||||
after_save :add_user_info
|
||||
|
||||
serialize :data_bank, JSON
|
||||
|
||||
def action_name
|
||||
case action_type
|
||||
when "DestroyUser" then "用户注销"
|
||||
when "DestroyUser" then "删除用户"
|
||||
when "DestroyProject" then "删除项目"
|
||||
when "Login" then "登录"
|
||||
when "Logout" then "退出登录"
|
||||
when "DestroyOrganization" then "删除组织"
|
||||
when "Attachment" then "上传附件"
|
||||
else self.action_type
|
||||
end
|
||||
end
|
||||
|
|
@ -42,7 +46,7 @@ class UserAction < ApplicationRecord
|
|||
def opt_user_name
|
||||
user = User.find_by(id: self.user_id)
|
||||
if user.present?
|
||||
user&.login
|
||||
user&.real_name
|
||||
else
|
||||
del_user = UserAction.find_by(action_type: "DestroyUser", action_id: self.user_id)
|
||||
del_user.present? ? del_user.user.login : "不存在用户:#{user_id}"
|
||||
|
|
@ -53,6 +57,14 @@ class UserAction < ApplicationRecord
|
|||
case action_type
|
||||
when "DestroyUser" then "账号:#{user&.login}<br/>邮箱:#{user&.mail}<br/>手机号:#{user&.phone}<br/>昵称:#{user&.nickname}<br/>"
|
||||
when "DestroyProject" then "项目名称:#{project&.name}<br/>项目标识:#{project&.identifier}<br/>"
|
||||
when "DestroyOrganization" then "组织名称:#{organization&.nickname}<br/>组织标识:#{organization&.login}<br/>"
|
||||
when 'Attachment'
|
||||
issue = Issue.find_by_id(attachment.container_id)
|
||||
if attachment.container_type == "Issue" && issue&.issue_classify == "issue"
|
||||
return "上传附件issue地址:<a href=\"#{Rails.application.config_for(:configuration)['platform_url']}/#{issue&.project&.owner&.login}/#{issue&.project&.identifier}/issues/#{issue&.project_issues_index}\">#{issue&.subject}</a>"
|
||||
else
|
||||
return "上传附件地址:<a href=\"#{Rails.application.config_for(:configuration)['platform_url']}/attachments/#{attachment.uuid}\">#{attachment.title}</a>"
|
||||
end
|
||||
else "--"
|
||||
end
|
||||
end
|
||||
|
|
@ -74,6 +86,26 @@ class UserAction < ApplicationRecord
|
|||
end
|
||||
action_project
|
||||
end
|
||||
|
||||
def organization
|
||||
action_organization = if action_type == "DestroyOrganization" && data_bank.present?
|
||||
build_mode("Organization")
|
||||
else
|
||||
Organization.find_by(id: self.action_id)
|
||||
end
|
||||
action_organization
|
||||
end
|
||||
|
||||
def attachment
|
||||
action_attachment = if action_type == "Attachment" && data_bank.present?
|
||||
build_mode("Attachment")
|
||||
else
|
||||
Attachment.find_by(id: self.action_id)
|
||||
end
|
||||
action_attachment
|
||||
end
|
||||
|
||||
|
||||
def build_mode(model_name)
|
||||
model = model_name.constantize.new
|
||||
model_name.constantize.column_names.each do |col|
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ class Admins::SaveLaboratorySettingService < ApplicationService
|
|||
save_image_file(params[:nav_logo], 'nav')
|
||||
save_image_file(params[:login_logo], 'login')
|
||||
save_image_file(params[:tab_logo], 'tab')
|
||||
save_image_file(params[:pm_logo], 'pm_logo')
|
||||
save_image_file(params[:subject_banner], '_subject_banner')
|
||||
save_image_file(params[:course_banner], '_course_banner')
|
||||
save_image_file(params[:competition_banner], '_competition_banner')
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue