| @@ -1,11 +1,3 @@ | |||
| GIT | |||
| remote: https://gitlink.org.cn/KingChan/sonarqube.git | |||
| revision: 80f07d427322ef02c0714c77a382e87aed0bef81 | |||
| specs: | |||
| sonarqube (1.3.0) | |||
| httparty (~> 0.14, >= 0.14.0) | |||
| terminal-table (~> 1.5, >= 1.5.1) | |||
| GEM | |||
| remote: https://mirrors.cloud.tencent.com/rubygems/ | |||
| specs: | |||
| @@ -107,6 +99,7 @@ GEM | |||
| archive-zip (~> 0.10) | |||
| nokogiri (~> 1.8) | |||
| chunky_png (1.3.11) | |||
| coderay (1.1.3) | |||
| concurrent-ruby (1.1.6) | |||
| connection_pool (2.2.2) | |||
| crass (1.0.6) | |||
| @@ -143,7 +136,7 @@ GEM | |||
| fugit (1.4.1) | |||
| et-orbi (~> 1.1, >= 1.1.8) | |||
| raabro (~> 1.4) | |||
| gitea-client (1.4.6) | |||
| gitea-client (1.5.9) | |||
| rest-client (~> 2.1.0) | |||
| globalid (0.4.2) | |||
| activesupport (>= 4.2.0) | |||
| @@ -156,11 +149,8 @@ GEM | |||
| hashie (3.6.0) | |||
| htmlentities (4.3.4) | |||
| http-accept (1.7.0) | |||
| http-cookie (1.0.5) | |||
| http-cookie (1.0.8) | |||
| domain_name (~> 0.5) | |||
| httparty (0.21.0) | |||
| mini_mime (>= 1.0.0) | |||
| multi_xml (>= 0.5.2) | |||
| i18n (1.8.2) | |||
| concurrent-ruby (~> 1.0) | |||
| io-like (0.3.1) | |||
| @@ -189,7 +179,8 @@ GEM | |||
| rb-fsevent (~> 0.9, >= 0.9.4) | |||
| rb-inotify (~> 0.9, >= 0.9.7) | |||
| ruby_dep (~> 1.2) | |||
| loofah (2.4.0) | |||
| logger (1.6.6) | |||
| loofah (2.20.0) | |||
| crass (~> 1.0.2) | |||
| nokogiri (>= 1.5.9) | |||
| mail (2.7.1) | |||
| @@ -198,9 +189,10 @@ GEM | |||
| mimemagic (~> 0.3.2) | |||
| maruku (0.7.3) | |||
| method_source (0.9.2) | |||
| mime-types (3.5.2) | |||
| mime-types (3.6.0) | |||
| logger | |||
| mime-types-data (~> 3.2015) | |||
| mime-types-data (3.2024.0507) | |||
| mime-types-data (3.2025.0220) | |||
| mimemagic (0.3.10) | |||
| nokogiri (~> 1) | |||
| rake | |||
| @@ -255,6 +247,11 @@ GEM | |||
| popper_js (1.16.0) | |||
| powerpack (0.1.2) | |||
| prettier (0.18.2) | |||
| pry (0.12.2) | |||
| coderay (~> 1.1.0) | |||
| method_source (~> 0.9.0) | |||
| pry-rails (0.3.9) | |||
| pry (>= 0.10.4) | |||
| public_suffix (4.0.3) | |||
| puma (5.6.5) | |||
| nio4r (~> 2.0) | |||
| @@ -448,8 +445,6 @@ GEM | |||
| actionpack (>= 4.0) | |||
| activesupport (>= 4.0) | |||
| sprockets (>= 3.0.0) | |||
| terminal-table (1.8.0) | |||
| unicode-display_width (~> 1.1, >= 1.1.1) | |||
| thor (1.0.1) | |||
| thread_safe (0.3.6) | |||
| tilt (2.0.10) | |||
| @@ -460,9 +455,7 @@ GEM | |||
| thread_safe (~> 0.1) | |||
| uglifier (4.2.0) | |||
| execjs (>= 0.3.0, < 3) | |||
| unf (0.1.4) | |||
| unf_ext | |||
| unf_ext (0.0.9.1) | |||
| unf (0.2.0) | |||
| unicode-display_width (1.6.1) | |||
| web-console (3.7.0) | |||
| actionview (>= 5.0) | |||
| @@ -504,7 +497,7 @@ DEPENDENCIES | |||
| enumerize | |||
| faraday (~> 0.15.4) | |||
| font-awesome-sass (= 4.7.0) | |||
| gitea-client (~> 1.4.3) | |||
| gitea-client (~> 1.5.8) | |||
| grape-entity (~> 0.7.1) | |||
| groupdate (~> 4.1.0) | |||
| harmonious_dictionary (~> 0.0.1) | |||
| @@ -514,6 +507,7 @@ DEPENDENCIES | |||
| kaminari (~> 1.1, >= 1.1.1) | |||
| letter_avatar | |||
| listen (>= 3.0.5, < 3.2) | |||
| loofah (~> 2.20.0) | |||
| mysql2 (>= 0.4.4, < 0.6.0) | |||
| oauth2 | |||
| omniauth (~> 1.9.0) | |||
| @@ -526,6 +520,7 @@ DEPENDENCIES | |||
| parallel (~> 1.19, >= 1.19.1) | |||
| pdfkit | |||
| prettier | |||
| pry-rails | |||
| puma (~> 5.6.5) | |||
| rack-cors | |||
| rails (~> 5.2.0) | |||
| @@ -552,7 +547,6 @@ DEPENDENCIES | |||
| simple_xlsx_reader (~> 1.0.4) | |||
| sinatra | |||
| solargraph (~> 0.38.0) | |||
| sonarqube! | |||
| spreadsheet | |||
| spring | |||
| spring-watcher-listen (~> 2.0.0) | |||
| @@ -32,11 +32,12 @@ class AccountsController < ApplicationController | |||
| username = params[:username]&.gsub(/\s+/, "") | |||
| tip_exception("无法使用以下关键词:#{username},请重新命名") if ReversedKeyword.check_exists?(username) | |||
| email = params[:email]&.gsub(/\s+/, "") | |||
| phone = params[:phone]&.gsub(/\s+/, "") | |||
| password = params[:password] | |||
| platform = (params[:platform] || 'forge')&.gsub(/\s+/, "") | |||
| ActiveRecord::Base.transaction do | |||
| result = autologin_register(username, email, password, platform) | |||
| result = autologin_register(username, email, password, platform, phone) | |||
| if result[:message].blank? | |||
| render_ok({user: result[:user]}) | |||
| else | |||
| @@ -144,7 +145,7 @@ class AccountsController < ApplicationController | |||
| user = Users::RegisterService.call(register_params) | |||
| user.mail = "#{user.login}@example.org" if user.mail.blank? | |||
| password = decrypt(register_params[:password]) rescue "" | |||
| password = decrypt(register_params[:password]) rescue register_params[:password].to_s | |||
| password = password.strip | |||
| # gitea用户注册, email, username, password | |||
| @@ -195,7 +196,7 @@ class AccountsController < ApplicationController | |||
| # 用户登录 | |||
| def login | |||
| password = decrypt(login_params[:password]) rescue "" | |||
| password = decrypt(login_params[:password]) rescue login_params[:password].to_s | |||
| Users::LoginForm.new(login_params.merge!({password: password})).validate! | |||
| @user = User.try_to_login(params[:login], password) | |||
| @@ -225,9 +226,9 @@ class AccountsController < ApplicationController | |||
| end | |||
| def change_password | |||
| password = decrypt(params[:password]) rescue "" | |||
| new_password_repeat = decrypt(params[:new_password_repeat]) rescue "" | |||
| old_password = decrypt(params[:old_password]) rescue "" | |||
| password = decrypt(params[:password]) rescue params[:password].to_s | |||
| new_password_repeat = decrypt(params[:new_password_repeat]) rescue params[:new_password_repeat].to_s | |||
| old_password = decrypt(params[:old_password]) rescue params[:old_password] | |||
| return render_error("两次输入的密码不一致") if password.to_s != new_password_repeat.to_s | |||
| @user = User.find_by(login: params[:login]) | |||
| return render_forbidden unless User.current.login == @user&.login | |||
| @@ -67,9 +67,9 @@ class Action::NodeInputsController < ApplicationController | |||
| def node_input_params | |||
| if params.require(:action_node_input) | |||
| params.require(:action_node_input).permit(:name, :input_type, :description, :is_required, :sort_no) | |||
| params.require(:action_node_input).permit(:name, :input_type, :description, :is_required, :sort_no, :default_value) | |||
| else | |||
| params.permit(:name, :input_type, :description, :is_required, :sort_no) | |||
| params.permit(:name, :input_type, :description, :is_required, :sort_no, :default_value) | |||
| end | |||
| end | |||
| end | |||
| @@ -37,19 +37,22 @@ class Admins::ProjectsRankController < Admins::BaseController | |||
| def export_excel(data) | |||
| book = Spreadsheet::Workbook.new | |||
| sheet = book.create_worksheet :name => "项目活跃度排行" | |||
| sheet.row(0).concat %w(排名 项目全称 项目地址 得分 访问数 关注数 点赞数 fork数 疑修数 合并请求数 提交数) | |||
| sheet.row(0).concat %w(排名 项目全称 项目地址 项目分类 首次创建时间 外部迁移/独立创建 得分 访问数 关注数 点赞数 fork数 疑修数 合并请求数 提交数) | |||
| data.each_with_index do |d, index| | |||
| sheet[index+1,0] = index+1 | |||
| sheet[index+1,1] = "#{d&.project&.owner&.real_name}/#{d&.project&.name}" | |||
| sheet[index+1,2] = "#{Rails.application.config_for(:configuration)['platform_url']}/#{d&.project&.owner&.login}/#{d&.project&.identifier}" | |||
| sheet[index+1,3] = d.score | |||
| sheet[index+1,4] = d.visits | |||
| sheet[index+1,5] = d.watchers | |||
| sheet[index+1,6] = d.praises | |||
| sheet[index+1,7] = d.forks | |||
| sheet[index+1,8] = d.issues | |||
| sheet[index+1,9] = d.pullrequests | |||
| sheet[index+1,10] = d.commits | |||
| sheet[index+1,3] = d&.project&.project_category&.name | |||
| sheet[index+1,4] = d&.project&.created_on.present? ? d&.project&.created_on.strftime("%Y-%m-%d %H:%M:%S") : "" | |||
| sheet[index+1,5] = d&.project&.common? ? "独立创建" : "外部迁移" | |||
| sheet[index+1,6] = d.score | |||
| sheet[index+1,7] = d.visits | |||
| sheet[index+1,8] = d.watchers | |||
| sheet[index+1,9] = d.praises | |||
| sheet[index+1,10] = d.forks | |||
| sheet[index+1,11] = d.issues | |||
| sheet[index+1,12] = d.pullrequests | |||
| sheet[index+1,13] = d.commits | |||
| end | |||
| book.write "#{Rails.root}/public/项目活跃度排行.xls" | |||
| end | |||
| @@ -30,8 +30,8 @@ class Api::Pm::BaseController < ApplicationController | |||
| end | |||
| def load_issue | |||
| return render_parameter_missing if params[:pm_project_id].blank? | |||
| @issue = Issue.issue_issue.where(pm_project_id: params[:pm_project_id]).find_by_id(params[:issue_id]) | |||
| # return render_parameter_missing if params[:pm_project_id].blank? | |||
| @issue = Issue.issue_issue.find_by_id(params[:issue_id]) | |||
| render_not_found('疑修不存在!') if @issue.blank? | |||
| end | |||
| # 具有对仓库的管理权限 | |||
| @@ -19,7 +19,8 @@ class Api::Pm::DashboardsController < Api::Pm::BaseController | |||
| 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) | |||
| @issues = @all_issues.joins(:issue_participants).where(issue_participants: {participant_id: current_user.id}) | |||
| @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 = 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 | |||
| @@ -284,11 +284,18 @@ class Api::Pm::IssuesController < Api::Pm::BaseController | |||
| end | |||
| def load_issue | |||
| return render_parameter_missing if params[:pm_project_id].blank? | |||
| @issue = Issue.issue_issue.where(pm_project_id: params[:pm_project_id]).find_by_id(params[:id]) | |||
| # return render_parameter_missing if params[:pm_project_id].blank? | |||
| @issue = Issue.issue_issue.find_by_id(params[:id]) | |||
| render_not_found('疑修不存在!') if @issue.blank? | |||
| end | |||
| # def load_issue_by_index | |||
| # return render_parameter_missing if params[:pm_project_id].blank? || params[:pm_issue_type].blank? || params[:enterprise_identifier].blank? | |||
| # @issue = Issue.find_issues_by_pm(params[:enterprise_identifier], params[:pm_issue_type]) | |||
| # .find_by(pm_issue_type_index3: params[:index]) | |||
| # render_not_found('疑修不存在!') if @issue.blank? | |||
| # end | |||
| def load_issues | |||
| return render_error('请输入正确的ID数组!') unless params[:ids].is_a?(Array) | |||
| params[:ids].each do |id| | |||
| @@ -315,7 +322,7 @@ class Api::Pm::IssuesController < Api::Pm::BaseController | |||
| :update_begin_date, :update_end_date, | |||
| :sort_by, :sort_direction, :root_id, | |||
| :issue_tag_ids, :pm_project_id, :pm_sprint_id, :pm_issue_type, :pm_project_ids, | |||
| :status_ids, :ids, :exclude_ids, :pm_issue_types, :participator_id | |||
| :status_ids, :ids, :exclude_ids, :pm_issue_types, :participator_id, :enterprise_identifier | |||
| ) | |||
| end | |||
| @@ -327,6 +334,7 @@ class Api::Pm::IssuesController < Api::Pm::BaseController | |||
| :branch_name, :start_date, :due_date, :time_scale, | |||
| :subject, :description, :blockchain_token_num, :root_subject, | |||
| :pm_project_id, :pm_sprint_id, :pm_issue_type, :root_id, :link_able_id, :project_id, | |||
| :status_msg, :enterprise_identifier, | |||
| issue_tag_ids: [], | |||
| assigner_ids: [], | |||
| attachment_ids: [], | |||
| @@ -0,0 +1,77 @@ | |||
| class Api::Pm::PipelinesController < Api::Pm::BaseController | |||
| include RepositoriesHelper | |||
| def index | |||
| @owner = Owner.find_by(login: params[:owner_id].to_s) || Owner.find_by(id: params[:owner_id].to_s) | |||
| tip_exception('组织未找到') if @owner.blank? | |||
| unless @owner.is_a?(Organization) && @owner.is_member?(current_user.id) | |||
| tip_exception('没有查看组织的权限') | |||
| end | |||
| @project_ids = @owner.projects.ids | |||
| project_gpids = @owner.projects.pluck(:gpid) | |||
| action_runs = Gitea::ActionRun.where(owner_id: @owner.gitea_uid) | |||
| group_data = action_runs.where(status: [1,2]).group(:workflow_id, :status).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) | |||
| @run_result = [] | |||
| run_files.each do |file_info| | |||
| 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) | |||
| 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? ? { | |||
| id: last_action_run.id, | |||
| schedule: last_action_run.schedule_id > 0, | |||
| 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, | |||
| created: last_action_run.created, | |||
| updated: last_action_run.updated, | |||
| } : {} | |||
| total = 0 | |||
| 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 | |||
| end | |||
| @run_result << { | |||
| repo_id: last_action_run.repo_id, | |||
| filename: ".gitea/workflows/#{file}", | |||
| total: total, | |||
| success: success, | |||
| failure: failure | |||
| }.merge(last_action_run_json) | |||
| 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 = @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) | |||
| end | |||
| end | |||
| @@ -71,7 +71,7 @@ class Api::Pm::SprintIssuesController < Api::Pm::BaseController | |||
| begin | |||
| case complete_params[:complete_type].to_i | |||
| when 1 | |||
| @issues.update_all(status_id: 5) | |||
| @issues.update_all(status_id: 5, due_date: Time.now) | |||
| when 2 | |||
| @issues.update_all(pm_sprint_id: 0) | |||
| when 3 | |||
| @@ -0,0 +1,82 @@ | |||
| class Api::Pm::WeeklyIssuesController < Api::Pm::BaseController | |||
| def personal | |||
| @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']}) | |||
| @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_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]) | |||
| 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) | |||
| next_week_page = params[:next_week_page] || 1 | |||
| next_week_limit = params[:next_week_limit] || 15 | |||
| @next_week_all_issues = @next_week_all_issues.page(next_week_page).per(next_week_limit) | |||
| end | |||
| def group | |||
| @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) | |||
| @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| | |||
| this_project_id_requirements = @this_week_all_issues.where(pm_project_id: pm_project_id, pm_issue_type: 1) | |||
| this_project_id_tasks = @this_week_all_issues.where(pm_project_id: pm_project_id, pm_issue_type: 2) | |||
| this_project_id_bugs = @this_week_all_issues.where(pm_project_id: pm_project_id, pm_issue_type: 3) | |||
| this_project_id_close_requirements = this_project_id_requirements.where(status_id: [3,5]) | |||
| this_project_id_close_tasks = this_project_id_tasks.where(status_id: [3,5]) | |||
| this_project_id_close_bugs = this_project_id_bugs.where(status_id: [3,5]) | |||
| data[pm_project_id] = { | |||
| this_week_requirement_issues_count: this_project_id_requirements.count, | |||
| this_week_task_issues_count: this_project_id_tasks.count, | |||
| this_week_bug_issues_count: this_project_id_bugs.count, | |||
| close_requirement_issues_count: this_project_id_close_requirements.count, | |||
| close_task_issues_count: this_project_id_close_tasks.count, | |||
| close_bug_issues_count: this_project_id_close_bugs.count, | |||
| this_week_task_issues: this_project_id_tasks | |||
| } | |||
| end | |||
| render :json => data | |||
| end | |||
| def group_issues | |||
| @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? | |||
| @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 = 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']}) | |||
| @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_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) | |||
| next_week_page = params[:next_week_page] || 1 | |||
| next_week_limit = params[:next_week_limit] || 15 | |||
| @next_week_all_issues = @next_week_all_issues.page(next_week_page).per(next_week_limit) | |||
| end | |||
| end | |||
| @@ -4,7 +4,9 @@ class Api::V1::Projects::Actions::ActionsController < Api::V1::Projects::Actions | |||
| @files = $gitea_client.get_repos_contents_by_owner_repo_filepath(@project&.owner&.login, @project&.identifier, ".gitea/workflows") rescue [] | |||
| @workflows = params[:workflows].split(",") if params[:workflows].present? | |||
| @action_runs = Gitea::ActionRun.where(repo_id: @project.gpid) | |||
| @action_runs = @action_runs.where(id: params[:ids].split(",")) if params[:ids].present? | |||
| disabled_config = Gitea::RepoUnit.where(repo_id: @project.gpid, type: 10)&.first&.config | |||
| disabled_workflows = disabled_config.present? ? JSON.parse(disabled_config)["DisabledWorkflows"] : [] | |||
| @action_runs = @action_runs.where(id: params[:ids].split(",")) if params[:ids].present? | |||
| @action_runs = @action_runs.where(workflow_id: @workflows) if params[:workflows].present? | |||
| group_data = @action_runs.where(status: [1,2]).group(:workflow_id, :status).count | |||
| @result = [] | |||
| @@ -14,6 +16,7 @@ class Api::V1::Projects::Actions::ActionsController < Api::V1::Projects::Actions | |||
| end | |||
| last_action_run = @action_runs.where(workflow_id: file).order(updated: :desc).first | |||
| last_action_run_json = last_action_run.present? ? { | |||
| pipeline_id: Action::Pipeline.find_by(pipeline_name: file, project_id: @project.id), | |||
| id: last_action_run.id, | |||
| schedule: last_action_run.schedule_id > 0, | |||
| title: last_action_run.title, | |||
| @@ -47,6 +50,7 @@ class Api::V1::Projects::Actions::ActionsController < Api::V1::Projects::Actions | |||
| end | |||
| @result << { | |||
| filename: file, | |||
| disabled: disabled_workflows.include?(file.to_s), | |||
| name: file.to_s.gsub(".yml","").gsub(".yaml","") , | |||
| branch: last_action_run.present? ? last_action_run.ref.gsub("refs/heads/","") : @project.default_branch, | |||
| pipeline_type: pipeline_type, | |||
| @@ -1,9 +1,12 @@ | |||
| class Api::V1::Projects::Actions::RunsController < Api::V1::Projects::Actions::BaseController | |||
| def index | |||
| @result_object = Api::V1::Projects::Actions::Runs::ListService.call(@project, {workflow: params[:workflow], page: page, limit: limit}, current_user&.gitea_token) | |||
| @begin_num = (page.to_i - 1) * limit.to_i | |||
| # puts @result_object | |||
| @files = $gitea_client.get_repos_contents_by_owner_repo_filepath(@project&.owner&.login, @project&.identifier, ".gitea/workflows") 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) | |||
| @begin_num = (page.to_i - 1) * limit.to_i | |||
| end | |||
| end | |||
| def create | |||
| @@ -36,11 +36,13 @@ class Api::V1::Projects::BranchesController < Api::V1::BaseController | |||
| 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 destroy | |||
| @result_object = Api::V1::Projects::Branches::DeleteService.call(@project, params[: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 | |||
| @@ -59,6 +61,7 @@ class Api::V1::Projects::BranchesController < Api::V1::BaseController | |||
| def restore | |||
| @result_object = Api::V1::Projects::Branches::RestoreService.call(@project, params[:branch_id], params[:branch_name], current_user&.gitea_token) | |||
| if @result_object | |||
| @project.update_column(:updated_on, Time.now) | |||
| return render_ok | |||
| else | |||
| return render_error('恢复分支失败!') | |||
| @@ -70,6 +73,7 @@ class Api::V1::Projects::BranchesController < Api::V1::BaseController | |||
| def update_default_branch | |||
| @result_object = Api::V1::Projects::Branches::UpdateDefaultBranchService.call(@project, params[:name], current_user&.gitea_token) | |||
| if @result_object | |||
| @project.update_column(:updated_on, Time.now) | |||
| return render_ok | |||
| else | |||
| return render_error('更新默认分支失败!') | |||
| @@ -1,9 +1,65 @@ | |||
| class Api::V1::Projects::PipelinesController < Api::V1::BaseController | |||
| include RepositoriesHelper | |||
| 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 | |||
| 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 | |||
| 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, | |||
| schedule: last_action_run.schedule_id > 0, | |||
| 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, | |||
| created: last_action_run.created, | |||
| updated: last_action_run.updated, | |||
| } : {} | |||
| total = 0 | |||
| 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 | |||
| end | |||
| @run_result << { | |||
| filename: ".gitea/workflows/#{file}", | |||
| total: total, | |||
| success: success, | |||
| failure: failure | |||
| }.merge(last_action_run_json) | |||
| end | |||
| # Rails.logger.info("@run_result======#{@run_result}") | |||
| disabled_config = Gitea::RepoUnit.where(repo_id: @project.gpid, type: 10)&.first&.config | |||
| @disabled_workflows = disabled_config.present? ? JSON.parse(disabled_config)["DisabledWorkflows"] : [] | |||
| @pipelines = Action::Pipeline.where(project_id: @project.id).order(updated_at: :desc) | |||
| @pipelines = paginate @pipelines | |||
| @pipelines = kaminari_paginate(@pipelines) | |||
| end | |||
| def test_yaml | |||
| @@ -17,37 +73,44 @@ class Api::V1::Projects::PipelinesController < Api::V1::BaseController | |||
| end | |||
| def create | |||
| size = Action::Pipeline.where(pipeline_name: params[:pipeline_name], project_id: @project.id).size | |||
| tip_exception("已经存在#{params[:pipeline_name]}流水线!") if size > 0 | |||
| @pipeline = Action::Pipeline.new(pipeline_name: params[:pipeline_name], project_id: @project.id) | |||
| @pipeline = params[:id].present? ? Action::Pipeline.find(params[:id]) : Action::Pipeline.find_or_initialize_by(pipeline_name: params[:pipeline_name], project_id: @project.id) | |||
| 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}")) | |||
| tip_exception(interactor.error) unless interactor.success? | |||
| end | |||
| end | |||
| end | |||
| @pipeline.pipeline_name = params[:pipeline_name] | |||
| @pipeline.file_name = ".gitea/workflows/#{@pipeline.pipeline_name}.yml" | |||
| @pipeline.branch = params[:branch] || @project.default_branch | |||
| @pipeline.json = params[:pipeline_json].to_json | |||
| pipeline_yaml = build_pipeline_yaml(params[:pipeline_name], params[:pipeline_json]) | |||
| tip_exception("流水线yaml内空不能为空") if pipeline_yaml.blank? | |||
| @pipeline.yaml = pipeline_yaml | |||
| @pipeline.is_graphic_design = params[:pipeline_type] == 2 ? true : false | |||
| @pipeline.pipeline_type = params[:pipeline_type] if params[:pipeline_type].present? | |||
| @pipeline.save! | |||
| sha = get_pipeline_file_sha(@pipeline.file_name, @pipeline.branch) | |||
| tip_exception("#{@pipeline.file_name}已存在") if sha | |||
| interactor = Gitea::CreateFileInteractor.call(current_user.gitea_token, @owner.login, content_params("create")) | |||
| tip_exception(interactor.error) unless interactor.success? | |||
| render_ok({ id: @pipeline.id }) | |||
| end | |||
| def save_yaml | |||
| @pipeline = Action::Pipeline.new(pipeline_name: params[:pipeline_name], project_id: @project.id) | |||
| @pipeline = params[:id].present? ? Action::Pipeline.find(params[:id]) : Action::Pipeline.find_or_initialize_by(pipeline_name: params[:pipeline_name], project_id: @project.id) | |||
| @pipeline.file_name = ".gitea/workflows/#{@pipeline.pipeline_name}.yml" | |||
| @pipeline.branch = params[:branch] || @project.default_branch | |||
| @pipeline.json = params[:pipeline_json].to_json | |||
| pipeline_yaml = build_pipeline_yaml_new(params[:pipeline_name], params[:pipeline_json]) | |||
| @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? | |||
| @pipeline.yaml = pipeline_yaml | |||
| Rails.logger.info "pipeline_yaml base64=========================#{Base64.encode64(@pipeline.yaml).gsub(/\n/, '')}" | |||
| #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")) | |||
| tip_exception(interactor.error) unless interactor.success? | |||
| file = interactor.result | |||
| render_ok({ pipeline_yaml: pipeline_yaml, pipeline_name: params[:pipeline_name], file_name: @pipeline.file_name, sha: sha.present? ? sha : file['content']['sha'] }) | |||
| @pipeline.pipeline_type = @pipeline.json.present? ? 2 : 1 | |||
| @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 | |||
| def build_yaml | |||
| @@ -79,15 +142,18 @@ class Api::V1::Projects::PipelinesController < Api::V1::BaseController | |||
| def destroy | |||
| @pipeline = Action::Pipeline.find(params[:id]) | |||
| if pipeline | |||
| interactor = Gitea::DeleteFileInteractor.call(current_user.gitea_token, @owner.login, content_params("update")) | |||
| tip_exception(interactor.error) unless interactor.success? | |||
| if @pipeline | |||
| sha = get_pipeline_file_sha(@pipeline.file_name, @pipeline.branch) | |||
| if sha.present? | |||
| 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 | |||
| @pipeline.destroy! | |||
| end | |||
| render_ok | |||
| end | |||
| def upload_results | |||
| tip_exception("参数错误") if params[:owner].blank? || params[:repo].blank? || params[:run_id].blank? | |||
| @project, @owner = Project.find_with_namespace(params[:owner], params[:repo]) | |||
| @@ -108,13 +174,15 @@ class Api::V1::Projects::PipelinesController < Api::V1::BaseController | |||
| tip_exception("参数错误") if params[:owner].blank? || params[:repo].blank? || params[:run_id].blank? | |||
| @project, @owner = Project.find_with_namespace(params[:owner], params[:repo]) | |||
| tip_exception("项目不存在") if @project.blank? | |||
| results = Action::PipelineResult.where(run_id: params[:run_id], project_id: @project.id) | |||
| results = Action::PipelineResult.where(run_id: params[:run_id], project_id: @project.id) | |||
| render_ok(run_results: results.as_json(only: %i[id run_id job_name job_show_type job_result])) | |||
| end | |||
| def show | |||
| @pipeline = Action::Pipeline.find_by(id: params[:id]) | |||
| @pipeline = Action::Pipeline.new(id: 0, pipeline_name: "test-ss", yaml: build_test_yaml) if @pipeline.blank? | |||
| disabled_config = Gitea::RepoUnit.where(repo_id: @project.gpid, type: 10)&.first&.config | |||
| @disabled_workflows = disabled_config.present? ? JSON.parse(disabled_config)["DisabledWorkflows"] : [] | |||
| # @pipeline = Action::Pipeline.new(id: 0, pipeline_name: "test-ss", yaml: build_test_yaml) if @pipeline.blank? | |||
| end | |||
| def build_pipeline_yaml_new(pipeline_name, pipeline_json) | |||
| @@ -157,9 +225,9 @@ class Api::V1::Projects::PipelinesController < Api::V1::BaseController | |||
| end | |||
| end | |||
| def content_params(opt) | |||
| def content_params(opt, rename_file=nil) | |||
| { | |||
| filepath: ".gitea/workflows/#{@pipeline.pipeline_name}.yml", | |||
| filepath: ".gitea/workflows/#{rename_file.present? ? rename_file : @pipeline.pipeline_name}.yml", | |||
| branch: @pipeline.branch, | |||
| new_branch: @pipeline.branch, | |||
| content: opt == "create" ? Base64.encode64(@pipeline.yaml).gsub(/\n/, '') : @pipeline.yaml, | |||
| @@ -172,6 +240,15 @@ class Api::V1::Projects::PipelinesController < Api::V1::BaseController | |||
| } | |||
| end | |||
| def del_content_params(sha) | |||
| { | |||
| filepath: ".gitea/workflows/#{@pipeline.pipeline_name}.yml", | |||
| base64_filepath: Base64.encode64(".gitea/workflows/#{@pipeline.pipeline_name}.yml").gsub(/\n/, ''), | |||
| branch: @pipeline.branch, | |||
| sha: sha | |||
| } | |||
| end | |||
| def build_nodes(params_nodes) | |||
| steps_nodes = [] | |||
| params_nodes.each do |input_node| | |||
| @@ -2,51 +2,203 @@ class Api::V1::Projects::PortraitController < Api::V1::BaseController | |||
| before_action :require_public_and_member_above | |||
| def index | |||
| platform_statistic = $redis_cache.hgetall("v2-platform-statistic") | |||
| Cache::V2::PlatformStatisticService.new().reset | |||
| @platform_statistic = $redis_cache.hgetall("v2-platform-statistic") | |||
| # 社区影响力 | |||
| praise_count = PraiseTread.where(praise_tread_object_type: "Project", praise_tread_object_id: @project.id).count | |||
| praise_count = PraiseTread.where(praise_tread_object_type: "Project", praise_tread_object_id: @project.id).count | |||
| watcher_count = Watcher.where(watchable_type:"Project", watchable_id: @project.id).count | |||
| fork_count = ForkUser.where(project_id: @project.id).count | |||
| community_impact_praise = platform_statistic['max-praise-count'].to_i == 0 ? 0 : 30*(praise_count.to_f/platform_statistic['max-praise-count'].to_i) | |||
| community_impact_watcher = platform_statistic['max-watcher-count'].to_i == 0 ? 0 : 30*(watcher_count.to_f/platform_statistic['max-watcher-count'].to_i) | |||
| community_impact_fork = platform_statistic['max-fork-count'].to_i == 0 ? 0 : 40*(fork_count.to_f/platform_statistic['max-fork-count'].to_i) | |||
| community_impact_praise = @platform_statistic['max-praise-count'].to_i == 0 ? 0 : 30*(praise_count.to_f/@platform_statistic['max-praise-count'].to_i) | |||
| community_impact_watcher = @platform_statistic['max-watcher-count'].to_i == 0 ? 0 : 30*(watcher_count.to_f/@platform_statistic['max-watcher-count'].to_i) | |||
| community_impact_fork = @platform_statistic['max-fork-count'].to_i == 0 ? 0 : 40*(fork_count.to_f/@platform_statistic['max-fork-count'].to_i) | |||
| community_impact = format("%.2f", community_impact_praise + community_impact_watcher + community_impact_fork) | |||
| # 项目成熟度 | |||
| pullrequest_count = PullRequest.where(project_id: @project.id).count | |||
| issue_count = Issue.issue_issue.where(project_id: @project.id).count | |||
| commit_count = CommitLog.joins(:project).merge(Project.common).where(project_id: @project.id).count | |||
| project_maturity_pullrequest = platform_statistic['max-pullrequest-count'].to_i == 0 ? 0 : 30*(pullrequest_count.to_f/platform_statistic['max-pullrequest-count'].to_i) | |||
| project_maturity_issue = platform_statistic['max-issue-count'].to_i == 0 ? 0 : 30*(issue_count.to_f/platform_statistic['max-issue-count'].to_i) | |||
| project_maturity_commit = platform_statistic['max-commit-count'].to_i == 0 ? 0 : 40*(commit_count.to_f/platform_statistic['max-commit-count'].to_i) | |||
| project_maturity = format("%.2f", project_maturity_pullrequest + project_maturity_issue + project_maturity_commit) | |||
| pullrequest_count = PullRequest.where(project_id: @project.id).count | |||
| complete_issue_count = Issue.issue_issue.where(project_id: @project.id, status_id: [3,5]).count | |||
| project_create_day = (Time.now.to_i - @project.created_on.to_i)/(3600*24) | |||
| max_project_create_day = (Time.now.to_i - Project.order("created_on desc").last.created_on.to_i)/(3600*24) | |||
| project_maturity_pullrequest = @platform_statistic['max-pullrequest-count'].to_i == 0? 0 : 40*(pullrequest_count.to_f/@platform_statistic['max-pullrequest-count'].to_i) | |||
| project_maturity_complete_issue = @platform_statistic['max-complete-issue-count'].to_i == 0? 0 : 40*(complete_issue_count.to_f/@platform_statistic['max-complete-issue-count'].to_i) | |||
| project_maturity_project_create_day = max_project_create_day.to_i <= 0 || project_create_day.to_i <= 0 ? 0 : 20*(Math.sqrt(project_create_day).to_f/Math.sqrt(max_project_create_day)) | |||
| project_maturity = format("%.2f", project_maturity_pullrequest + project_maturity_complete_issue + project_maturity_project_create_day) | |||
| # 项目健康度 | |||
| closed_pullrequest_count = PullRequest.where(project_id: @project.id).merged_and_closed.count | |||
| closed_issue_count = Issue.issue_issue.where(project_id: @project.id).closed.count | |||
| member_count = Member.where(project_id: @project.id).count | |||
| max_member_count = @platform_statistic['max-member-count'].to_i | |||
| project_last_commit = CommitLog.joins(:project).merge(Project.common).where(project_id: @project.id).order("created_at desc").first | |||
| last_commit_day = project_last_commit.present? ? (Time.now.to_i - project_last_commit.created_at.to_i)/(3600*24) : 0 | |||
| has_license = @project.license.present? ? 1 : 0 | |||
| project_health_issue = (issue_count < 10 || closed_issue_count < 10) ? 0 : 40*(closed_issue_count-10).to_f/(issue_count-10) | |||
| project_health_pullrequest = (pullrequest_count < 5 || closed_pullrequest_count < 5) ? 0 : 30*(closed_pullrequest_count-5).to_f/(pullrequest_count-5) | |||
| project_health_license = 20*has_license | |||
| project_health = format("%.2f", project_health_issue + project_health_pullrequest + project_health_license) | |||
| closed_pullrequest_count = PullRequest.where(project_id: @project.id).merged_and_closed.count | |||
| closed_issue_count = Issue.issue_issue.where(project_id: @project.id).closed.count | |||
| pullrequest_count = PullRequest.where(project_id: @project.id).count | |||
| issue_count = Issue.issue_issue.where(project_id: @project.id).count | |||
| health_code1 = max_member_count.to_i == 0 ? 0 : 0.3*(member_count.to_f/max_member_count) | |||
| health_code2 = last_commit_day.to_i == 0 ? 0 : 0.7*(1.to_f/(1+last_commit_day)) | |||
| health_code = 10 * (health_code1 + health_code2) | |||
| health_license = 10 * has_license | |||
| health_pullrequest = pullrequest_count <= 1 ? 0 : 40 * (closed_pullrequest_count.to_f/pullrequest_count)*(1-1/Math.sqrt(pullrequest_count+1)) | |||
| health_issue = issue_count <= 1 ? 0 : 40 * (closed_issue_count.to_f/issue_count)*(1-1/Math.sqrt(issue_count+1)) | |||
| project_health = format("%.2f", health_code + health_license + health_pullrequest + health_issue) | |||
| # 团队影响度 | |||
| member_count = Member.where(project_id: @project.id).count | |||
| recent_one_month_member_count = Member.where(project_id:@project.id).where("created_on > ?", Time.now - 30.days).count | |||
| team_impact_member = platform_statistic['max-member-count'].to_i == 0 ? 0 : 40*(member_count.to_f/platform_statistic['max-member-count'].to_i) | |||
| team_impact_recent_member = platform_statistic['max-recent-one-month-member-count'].to_i == 0 ? 0 : 60*(recent_one_month_member_count.to_f/platform_statistic['max-recent-one-month-member-count'].to_i) | |||
| team_impact = format("%.2f", team_impact_member + team_impact_recent_member) | |||
| member_count = Member.where(project_id: @project.id).count | |||
| max_member_count = @platform_statistic['max-member-count'].to_i | |||
| recent_one_month_member_count = Member.where(project_id:@project.id).where("created_on >?", Time.now - 30.days).count | |||
| max_recent_one_month_member_count = @platform_statistic['max-recent-one-month-member-count'].to_i | |||
| issue_assigner_count = IssueAssigner.joins(:issue).merge(Issue.issue_issue).where(issues: {project_id: @project.id}).distinct.count | |||
| team_impact_member = 40*(member_count.to_f/max_member_count) | |||
| team_impact_recent_member = 40*(recent_one_month_member_count.to_f/max_recent_one_month_member_count) | |||
| team_impact_issue_assigner = 20*(issue_assigner_count.to_f/max_member_count) | |||
| team_impact = format("%.2f", team_impact_member + team_impact_recent_member + team_impact_issue_assigner) | |||
| # 开发活跃度 | |||
| recent_one_month_pullrequest_count = PullRequest.where(project_id: @project.id).where("created_at > ?", Time.now - 30.days).count | |||
| recent_one_month_issue_count = Issue.issue_issue.where(project_id: @project.id).where("created_on > ?", Time.now - 30.days).count | |||
| recent_one_month_commit_count = CommitLog.joins(:project).merge(Project.common).where(project_id: @project.id).where("created_at > ?", Time.now - 30.days).count | |||
| develop_activity_pullrequest = platform_statistic['max-recent-one-month-pullrequest-count'].to_i == 0 ? 0 : 20*(recent_one_month_pullrequest_count.to_f/platform_statistic['max-recent-one-month-pullrequest-count'].to_i) | |||
| develop_activity_issue = platform_statistic['max-recent-one-month-issue-count'].to_i == 0 ? 0 : 20*(recent_one_month_issue_count.to_f/platform_statistic['max-recent-one-month-issue-count'].to_i) | |||
| develop_activity_commit = platform_statistic['max-recent-one-month-commit-count'].to_i == 0 ? 0 : 40*(recent_one_month_commit_count.to_f/platform_statistic['max-recent-one-month-commit-count'].to_i) | |||
| develop_activity = format("%.2f", 20 + develop_activity_pullrequest + develop_activity_issue + develop_activity_commit) | |||
| recent_one_month_commit_count = CommitLog.joins(:project).merge(Project.common).where(project_id: @project.id).where("created_at >?", Time.now - 30.days).count | |||
| recent_one_month_pullrequest_count = PullRequest.where(project_id: @project.id).where("created_at >?", Time.now - 30.days).count | |||
| recent_one_month_issue_count = Issue.issue_issue.where(project_id: @project.id).where("created_on >?", Time.now - 30.days).count | |||
| recent_one_month_release_count = VersionRelease.joins(:repository).where(repositories: {project_id: @project.id}).where("created_at >?", Time.now - 30.days).count | |||
| max_recent_one_month_commit_count = @platform_statistic['max-recent-one-month-commit-count'].to_i | |||
| max_recent_one_month_pullrequest_count = @platform_statistic['max-recent-one-month-pullrequest-count'].to_i | |||
| max_recent_one_month_issue_count = @platform_statistic['max-recent-one-month-issue-count'].to_i | |||
| max_recent_one_month_release_count = @platform_statistic['max-recent-one-month-release-count'].to_i | |||
| develop_activity_commit = max_recent_one_month_commit_count.zero? ? 0 : 40*(recent_one_month_commit_count.to_f/max_recent_one_month_commit_count) | |||
| develop_activity_issue = max_recent_one_month_issue_count.zero? ? 0 : 20*(recent_one_month_issue_count.to_f/max_recent_one_month_issue_count) | |||
| develop_activity_pullrequest = max_recent_one_month_pullrequest_count.zero? ? 0 : 20*(recent_one_month_pullrequest_count.to_f/max_recent_one_month_pullrequest_count) | |||
| develop_activity_release = max_recent_one_month_release_count.zero? ? 0 : 20*(recent_one_month_release_count.to_f/max_recent_one_month_release_count) | |||
| develop_activity = format("%.2f", develop_activity_commit + develop_activity_issue + develop_activity_pullrequest + develop_activity_release) | |||
| render :json => {community_impact: community_impact, project_maturity: project_maturity, project_health: project_health, team_impact: team_impact, develop_activity: develop_activity} | |||
| end | |||
| # 社区影响力 | |||
| def community_impact | |||
| Cache::V2::PlatformStatisticService.new().reset | |||
| @platform_statistic = $redis_cache.hgetall("v2-platform-statistic") | |||
| praise_count = PraiseTread.where(praise_tread_object_type: "Project", praise_tread_object_id: @project.id).count | |||
| watcher_count = Watcher.where(watchable_type:"Project", watchable_id: @project.id).count | |||
| fork_count = ForkUser.where(project_id: @project.id).count | |||
| community_impact_praise = @platform_statistic['max-praise-count'].to_i == 0 ? 0 : 30*(praise_count.to_f/@platform_statistic['max-praise-count'].to_i) | |||
| community_impact_watcher = @platform_statistic['max-watcher-count'].to_i == 0 ? 0 : 30*(watcher_count.to_f/@platform_statistic['max-watcher-count'].to_i) | |||
| community_impact_fork = @platform_statistic['max-fork-count'].to_i == 0 ? 0 : 40*(fork_count.to_f/@platform_statistic['max-fork-count'].to_i) | |||
| community_impact = format("%.2f", community_impact_praise + community_impact_watcher + community_impact_fork) | |||
| render :json => { | |||
| community_impact_praise: community_impact_praise, | |||
| community_impact_watcher: community_impact_watcher, | |||
| community_impact_fork: community_impact_fork, | |||
| community_impact: community_impact | |||
| } | |||
| end | |||
| # 项目成熟度 | |||
| def project_maturity | |||
| Cache::V2::PlatformStatisticService.new().reset | |||
| @platform_statistic = $redis_cache.hgetall("v2-platform-statistic") | |||
| pullrequest_count = PullRequest.where(project_id: @project.id).count | |||
| complete_issue_count = Issue.issue_issue.where(project_id: @project.id, status_id: [3,5]).count | |||
| project_create_day = (Time.now.to_i - @project.created_on.to_i)/(3600*24) | |||
| max_project_create_day = (Time.now.to_i - Project.order("created_on desc").last.created_on.to_i)/(3600*24) | |||
| project_maturity_pullrequest = @platform_statistic['max-pullrequest-count'].to_i == 0? 0 : 40*(pullrequest_count.to_f/@platform_statistic['max-pullrequest-count'].to_i) | |||
| project_maturity_complete_issue = @platform_statistic['max-complete-issue-count'].to_i == 0? 0 : 40*(complete_issue_count.to_f/@platform_statistic['max-complete-issue-count'].to_i) | |||
| project_maturity_project_create_day = max_project_create_day.to_i <= 0 || project_create_day.to_i <= 0 ? 0 : 20*(Math.sqrt(project_create_day).to_f/Math.sqrt(max_project_create_day)) | |||
| project_maturity = format("%.2f", project_maturity_pullrequest + project_maturity_complete_issue + project_maturity_project_create_day) | |||
| render :json => { | |||
| project_maturity_pullrequest: project_maturity_pullrequest, | |||
| project_maturity_complete_issue: project_maturity_complete_issue, | |||
| project_maturity_project_create_day: project_maturity_project_create_day, | |||
| project_maturity: project_maturity | |||
| } | |||
| end | |||
| # 项目健康度 | |||
| def project_health | |||
| Cache::V2::PlatformStatisticService.new().reset | |||
| @platform_statistic = $redis_cache.hgetall("v2-platform-statistic") | |||
| member_count = Member.where(project_id: @project.id).count | |||
| max_member_count = @platform_statistic['max-member-count'].to_i | |||
| project_last_commit = CommitLog.joins(:project).merge(Project.common).where(project_id: @project.id).order("created_at desc").first | |||
| last_commit_day = project_last_commit.present? ? (Time.now.to_i - project_last_commit.created_at.to_i)/(3600*24) : 0 | |||
| has_license = @project.license.present? ? 1 : 0 | |||
| closed_pullrequest_count = PullRequest.where(project_id: @project.id, status: 1).count | |||
| closed_issue_count = Issue.issue_issue.where(project_id: @project.id, status_id: [3,5]).count | |||
| pullrequest_count = PullRequest.where(project_id: @project.id).count | |||
| issue_count = Issue.issue_issue.where(project_id: @project.id).count | |||
| health_code1 = max_member_count.to_i == 0 ? 0 : 0.3*(member_count.to_f/max_member_count) | |||
| health_code2 = last_commit_day.to_i == 0 ? 0 : 0.7*(1.to_f/(1+last_commit_day*0.1)) | |||
| health_code = 10 * (health_code1 + health_code2) | |||
| health_license = 10 * has_license | |||
| health_pullrequest = pullrequest_count <= 1 ? 0 : 40 * (closed_pullrequest_count.to_f/pullrequest_count)*(1-1/Math.sqrt(pullrequest_count+1)) | |||
| health_issue = issue_count <= 1 ? 0 : 40 * (closed_issue_count.to_f/issue_count)*(1-1/Math.sqrt(issue_count+1)) | |||
| project_health = format("%.2f", health_code + health_license + health_pullrequest + health_issue) | |||
| render :json => { | |||
| health_code: health_code, | |||
| health_license: health_license, | |||
| health_pullrequest: health_pullrequest, | |||
| health_issue: health_issue, | |||
| project_health: project_health | |||
| } | |||
| end | |||
| # 团队健康度 | |||
| def team_impact | |||
| Cache::V2::PlatformStatisticService.new().reset | |||
| @platform_statistic = $redis_cache.hgetall("v2-platform-statistic") | |||
| member_count = Member.where(project_id: @project.id).count | |||
| max_member_count = @platform_statistic['max-member-count'].to_i | |||
| recent_one_month_member_count = Member.where(project_id:@project.id).where("created_on >?", Time.now - 30.days).count | |||
| max_recent_one_month_member_count = @platform_statistic['max-recent-one-month-member-count'].to_i | |||
| issue_assigner_count = IssueAssigner.joins(:issue).merge(Issue.issue_issue).where(issues: {project_id: @project.id}).distinct.count | |||
| project_member_count = @project.owner.is_a?(User) ? member_count : @project.owner.organization_users.count | |||
| team_impact_member = 40*(member_count.to_f/max_member_count) | |||
| team_impact_recent_member = 40*(recent_one_month_member_count.to_f/max_recent_one_month_member_count) | |||
| team_impact_issue_assigner = 20*(issue_assigner_count.to_f/project_member_count) | |||
| team_impact = format("%.2f", team_impact_member + team_impact_recent_member + team_impact_issue_assigner) | |||
| render :json => { | |||
| team_impact_member: team_impact_member, | |||
| team_impact_recent_member: team_impact_recent_member, | |||
| team_impact_issue_assigner: team_impact_issue_assigner, | |||
| team_impact: team_impact | |||
| } | |||
| end | |||
| # 开发活跃度 | |||
| def develop_activity | |||
| Cache::V2::PlatformStatisticService.new().reset | |||
| @platform_statistic = $redis_cache.hgetall("v2-platform-statistic") | |||
| recent_one_month_commit_count = CommitLog.joins(:project).merge(Project.common).where(project_id: @project.id).where("created_at >?", Time.now - 30.days).count | |||
| recent_one_month_pullrequest_count = PullRequest.where(project_id: @project.id).where("created_at >?", Time.now - 30.days).count | |||
| recent_one_month_issue_count = Issue.issue_issue.where(project_id: @project.id).where("created_on >?", Time.now - 30.days).count | |||
| recent_one_month_release_count = VersionRelease.joins(:repository).where(repositories: {project_id: @project.id}).where("created_at >?", Time.now - 30.days).count | |||
| max_recent_one_month_commit_count = @platform_statistic['max-recent-one-month-commit-count'].to_i | |||
| max_recent_one_month_pullrequest_count = @platform_statistic['max-recent-one-month-pullrequest-count'].to_i | |||
| max_recent_one_month_issue_count = @platform_statistic['max-recent-one-month-issue-count'].to_i | |||
| max_recent_one_month_release_count = @platform_statistic['max-recent-one-month-release-count'].to_i | |||
| develop_activity_commit = max_recent_one_month_commit_count.zero? ? 0 : 40*(recent_one_month_commit_count.to_f/max_recent_one_month_commit_count) | |||
| develop_activity_issue = max_recent_one_month_issue_count.zero? ? 0 : 20*(recent_one_month_issue_count.to_f/max_recent_one_month_issue_count) | |||
| develop_activity_pullrequest = max_recent_one_month_pullrequest_count.zero? ? 0 : 20*(recent_one_month_pullrequest_count.to_f/max_recent_one_month_pullrequest_count) | |||
| develop_activity_release = max_recent_one_month_release_count.zero? ? 0 : 20*(recent_one_month_release_count.to_f/max_recent_one_month_release_count) | |||
| develop_activity = format("%.2f", develop_activity_commit + develop_activity_issue + develop_activity_pullrequest + develop_activity_release) | |||
| render :json => { | |||
| develop_activity_commit: develop_activity_commit, | |||
| develop_activity_issue: develop_activity_issue, | |||
| develop_activity_pullrequest: develop_activity_pullrequest, | |||
| develop_activity_release: develop_activity_release, | |||
| develop_activity: develop_activity | |||
| } | |||
| end | |||
| end | |||
| @@ -1,5 +1,8 @@ | |||
| class Api::V1::SonarqubesController < Api::V1::BaseController | |||
| before_action :load_repository | |||
| include Repository::LanguagesPercentagable | |||
| include SonarService | |||
| def sonar_initialize | |||
| gitea_params = { has_actions: params[:has_actions] == 'true' ? true :false } | |||
| gitea_setting = Gitea::Repository::UpdateService.call(@owner, @project.identifier, gitea_params) | |||
| @@ -17,6 +20,7 @@ class Api::V1::SonarqubesController < Api::V1::BaseController | |||
| def insert_file | |||
| checkout_url = 'https://gitlink.org.cn/KingChan/checkout@v4' | |||
| scanner_url = 'https://gitlink.org.cn/KingChan/sonarqube-scan-action@master' | |||
| doxygen_url = "https://gitlink.gitlink.net" | |||
| begin | |||
| config = Rails.application.config_for(:configuration) | |||
| sonarqube_config = config.dig('sonarqube') | |||
| @@ -27,7 +31,9 @@ class Api::V1::SonarqubesController < Api::V1::BaseController | |||
| if sonarqube_config.present? && sonarqube_config['scanner'].present? | |||
| scanner_url = sonarqube_config['scanner'] | |||
| end | |||
| if sonarqube_config.present? && sonarqube_config['doxygen'].present? | |||
| doxygen_url = sonarqube_config['doxygen'] | |||
| end | |||
| raise 'sonar config missing' if sonarqube_config.blank? | |||
| rescue => ex | |||
| raise ex if Rails.env.production? | |||
| @@ -61,6 +67,9 @@ class Api::V1::SonarqubesController < Api::V1::BaseController | |||
| with: | |||
| # Disabling shallow clones is recommended for improving the relevancy of reporting | |||
| fetch-depth: 0 | |||
| - name: curl doxygen | |||
| run: | | |||
| curl -X GET #{doxygen_url}/generate?repo=#{@project.repository.url} | |||
| - name: SonarQube Scan | |||
| uses: #{scanner_url} | |||
| env: | |||
| @@ -83,11 +92,13 @@ class Api::V1::SonarqubesController < Api::V1::BaseController | |||
| 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.projectKey=#{params[:owner]}-#{@project.id}\nsonar.sources=.\nsonar.java.binaries=.", | |||
| "content": sonar_content, | |||
| "message": 'Add sonar-project.properties', | |||
| committer: { | |||
| email: @owner.mail, | |||
| @@ -95,6 +106,7 @@ class Api::V1::SonarqubesController < Api::V1::BaseController | |||
| }, | |||
| 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'])) | |||
| @@ -148,6 +160,31 @@ class Api::V1::SonarqubesController < Api::V1::BaseController | |||
| render_ok data | |||
| end | |||
| def doxygen_url | |||
| config = Rails.application.config_for(:configuration) | |||
| sonarqube_config = config.dig('sonarqube') | |||
| doxygen_url = sonarqube_config['doxygen'] | |||
| data = {doxygen_url: "#{doxygen_url}/files/#{@project.owner.login}/#{@project.identifier}/html/"} | |||
| render_ok data | |||
| end | |||
| def analyze_doxygen | |||
| config = Rails.application.config_for(:configuration) | |||
| sonarqube_config = config.dig('sonarqube') | |||
| doxygen_url = sonarqube_config['doxygen'] | |||
| url = "#{doxygen_url}/files/#{@project.owner.login}/#{@project.identifier}/html/analyze_doxygen.json" | |||
| uri = URI.parse(url) | |||
| response = Net::HTTP.get_response(uri) | |||
| if response.code.to_i != 200 | |||
| puts "======= 接口请求失败!" | |||
| data = { data: nil, msg: '文件不存在' } | |||
| else | |||
| data = { data: JSON.parse(response.body), msg: 'ok' } | |||
| end | |||
| render_ok data | |||
| end | |||
| def measures_search_history | |||
| params_data = { | |||
| from: params[:form], | |||
| @@ -54,7 +54,7 @@ class Api::V1::UsersController < Api::V1::BaseController | |||
| end | |||
| def check_password | |||
| password = decrypt(params[:password]) rescue "" | |||
| password = decrypt(params[:password]) rescue params[:password].to_s | |||
| return tip_exception(-5, "8~16位密码,支持字母数字和符号") unless password =~ CustomRegexp::PASSWORD | |||
| return tip_exception(-5, "密码错误") unless @observe_user.check_password?(password) | |||
| render_ok | |||
| @@ -127,7 +127,7 @@ class Api::V1::UsersController < Api::V1::BaseController | |||
| def destroy | |||
| password = decrypt(params[:password]) rescue "" | |||
| password = decrypt(params[:password]) rescue params[:password].to_s | |||
| return tip_exception(-1, "密码不正确.") unless @observe_user.check_password?(password) | |||
| org_ids = TeamUser.where(user_id: @observe_user.id).pluck(:organization_id) | OrganizationUser.where(user_id: @observe_user.id).pluck(:organization_id) | |||
| org_count = TeamUser.where(organization_id: org_ids).where(user_id: @observe_user.id).joins(:team).where(teams: {authorize: %w(owner)}).count | |||
| @@ -421,24 +421,6 @@ class ApplicationController < ActionController::Base | |||
| "#{edu_setting('git_address_domain')}/#{repo_path}" | |||
| end | |||
| # 通关后,把最后一次成功的代码存到数据库 | |||
| # type 0 创始内容, 1 最新内容 | |||
| # def game_passed_code(path, myshixun, game_id) | |||
| # # 如果代码窗口是隐藏的,则不用保存代码 | |||
| # return if myshixun.shixun.hide_code || myshixun.shixun.vnc | |||
| # file_content = git_fle_content myshixun.repo_path, path | |||
| # #unless file_content.present? | |||
| # # raise("获取文件代码异常") | |||
| # #end | |||
| # logger.info("#######game_id:#{game_id}, file_content:#{file_content}") | |||
| # game_code = GameCode.where(:game_id => game_id, :path => path).first | |||
| # if game_code.nil? | |||
| # GameCode.create!(:game_id => game_id, :new_code => file_content, :path => path) | |||
| # else | |||
| # game_code.update_attributes!(:new_code => file_content) | |||
| # end | |||
| # end | |||
| # Post请求 | |||
| def uri_post(uri, params) | |||
| begin | |||
| @@ -530,112 +512,6 @@ class ApplicationController < ActionController::Base | |||
| end | |||
| # 实训主类别列表,自带描述 | |||
| def shixun_main_type | |||
| list = [] | |||
| mirrors = MirrorRepository.select([:id, :type_name, :description, :name]).published_main_mirror | |||
| mirrors.try(:each) do |mirror| | |||
| list << {id: mirror.id, type_name: mirror.type_name, description: mirror.try(:description), mirror_name: mirror.name} | |||
| end | |||
| list | |||
| end | |||
| # 小类别列表 | |||
| def shixun_small_type | |||
| list = [] | |||
| mirrors = MirrorRepository.select([:id, :type_name, :description, :name]).published_small_mirror | |||
| mirrors.try(:each) do |mirror| | |||
| list << {id: mirror.id, type_name: mirror.type_name, description: mirror.description, mirror_name: mirror.name} | |||
| end | |||
| list | |||
| end | |||
| def container_limit(mirror_repositories) | |||
| container = [] | |||
| mirror_repositories.each do |mr| | |||
| if mr.name.present? | |||
| container << {:image => mr.name, :cpuLimit => mr.cpu_limit, :memoryLimit => "#{mr.memory_limit}M", :type => mr.try(:main_type) == "1" ? "main" : "sub"} | |||
| end | |||
| end | |||
| container.to_json | |||
| end | |||
| # 实训中间层pod配置 | |||
| def shixun_container_limit shixun | |||
| container = [] | |||
| shixun.shixun_service_configs.each do |config| | |||
| mirror = config.mirror_repository | |||
| if mirror.name.present? | |||
| # 资源限制没有就传默认值。 | |||
| cpu_limit = config.cpu_limit.presence || 1 | |||
| cpu_request = config.lower_cpu_limit.presence || 0.1 | |||
| memory_limit = config.memory_limit.presence || 1024 | |||
| request_limit = config.request_limit.presence || 10 | |||
| resource_limit = config.resource_limit.presence || 10000 | |||
| container << {:image => mirror.name, | |||
| :cpuLimit => cpu_limit, | |||
| :cpuRequest => cpu_request, | |||
| :memoryLimit => "#{memory_limit}M", | |||
| :memoryRequest => "#{request_limit}M", | |||
| :resourceLimit => "#{resource_limit}K", | |||
| :type => mirror.try(:main_type) == "1" ? "main" : "sub"} | |||
| end | |||
| end | |||
| container.to_json | |||
| end | |||
| # 毕设任务列表的赛选 | |||
| def course_work(task, **option) | |||
| logger.info("#############{option}") | |||
| course = task.course | |||
| work_list = task.graduation_works.includes(user: [:user_extension]) | |||
| # 教师评阅搜索 0: 未评, 1 已评 | |||
| if option[:teacher_comment] | |||
| graduation_work_ids = GraduationWorkScore.where(graduation_work_id: work_list.map(&:id)).pluck(:graduation_work_id) | |||
| if option[:teacher_comment].zero? | |||
| work_list = work_list.where.not(id: graduation_work_ids) | |||
| elsif option[:teacher_comment] == 1 | |||
| work_list = work_list.where(id: graduation_work_ids).where.not(work_status: 0) | |||
| end | |||
| end | |||
| # 作品状态 0: 未提交, 1 按时提交, 2 延迟提交 | |||
| if option[:task_status] | |||
| work_list = work_list.where(work_status: option[:task_status]) | |||
| end | |||
| # 分班情况 | |||
| if option[:course_group] | |||
| group_user_ids = course.course_members.where(course_group_id: option[:course_group]).pluck(:user_id) | |||
| # 有分组只可能是老师身份查看列表 | |||
| work_list = work_list.where(user_id: group_user_ids) | |||
| end | |||
| # 只看我的交叉评阅 | |||
| if option[:cross_comment] | |||
| graduation_work_id = task.graduation_work_comment_assignations.where(:user_id => current_user.id) | |||
| .pluck(:graduation_work_id).uniq if task.graduation_work_comment_assignations | |||
| work_list = work_list.where(id: graduation_work_id) | |||
| end | |||
| # 输入姓名和学号搜索 | |||
| # TODO user_extension 如果修改 请调整 | |||
| if option[:search] | |||
| work_list = work_list.joins(user: :user_extension).where("concat(lastname, firstname) like ? | |||
| or student_id like ?", "%#{option[:search]}%", "%#{option[:search]}%") | |||
| end | |||
| # 排序 | |||
| rorder = UserExtension.column_names.include?(option[:order]) ? option[:order] : "updated_at" | |||
| b_order = %w(desc asc).include?(option[:b_order]) ? option[:b_order] : "desc" | |||
| if rorder == "created_at" || rorder == "work_score" | |||
| work_list = work_list.order("graduation_works.#{rorder} #{b_order}") | |||
| elsif rorder == "student_id" | |||
| work_list = work_list.joins(user: :user_extension).order("user_extensions.#{rorder} #{b_order}") | |||
| end | |||
| work_list | |||
| end | |||
| def strip_html(text, len=0, endss="...") | |||
| ss = "" | |||
| if !text.nil? && text.length>0 | |||
| @@ -1176,15 +1052,46 @@ class ApplicationController < ActionController::Base | |||
| # 接口限流,请求量大有性能问题 | |||
| def request_limit | |||
| record_count = Rails.cache.read("request/#{controller_name}/#{Time.now.strftime('%Y%m%d%H%M')}/#{request.remote_ip}") | |||
| white_list_ip = ["106.75.110.152"] | |||
| unless white_list_ip.include?(request.remote_ip) | |||
| record_count = Rails.cache.read("request/#{controller_name}/#{Time.now.strftime('%Y%m%d%H')}/#{request.remote_ip}") | |||
| if record_count.present? | |||
| record_count = record_count + 1 | |||
| else | |||
| record_count = 1 | |||
| end | |||
| Rails.logger.info("请求太快,请稍后再试。#{controller_name}::#{request.remote_ip}") if record_count > 200 | |||
| tip_exception("请求太快,请稍后再试。") if record_count > 200 | |||
| Rails.cache.write("request/#{controller_name}/#{Time.now.strftime('%Y%m%d%H')}/#{request.remote_ip}", record_count, expires_in: 1.hour) | |||
| end | |||
| end | |||
| def check_batch_requests | |||
| check_key = "request.remote_ip:#{request.remote_ip}" | |||
| result = Rails.cache.read(check_key) | |||
| if result.present? | |||
| if result.to_i > 100 | |||
| tip_exception(401, '暂时无法请求,请稍后再试') | |||
| else | |||
| Rails.cache.write(check_key, result.to_i + 1) | |||
| end | |||
| else | |||
| Rails.cache.write(check_key, 1, expires_in: 1.hour) | |||
| end | |||
| end | |||
| def request_raw_limit | |||
| record_count = Rails.cache.read("request/#{request.path}/#{Time.now.strftime('%Y%m%d%H')}}") | |||
| if record_count.present? | |||
| record_count = record_count + 1 | |||
| else | |||
| record_count = 1 | |||
| end | |||
| tip_exception("请求太快,请稍后再试。") if record_count > 100 | |||
| Rails.logger.info("请求太快,请稍后再试。#{request.path}") if record_count > 1000 | |||
| tip_exception("请求太快,请稍后再试。") if record_count > 1000 | |||
| Rails.cache.write("request/#{controller_name}/#{Time.now.strftime('%Y%m%d%H%M')}/#{request.remote_ip}", record_count, expires_in: 1.minute) | |||
| Rails.cache.write("request/#{request.path}/#{Time.now.strftime('%Y%m%d%H')}}", record_count, expires_in: 1.hour) | |||
| end | |||
| end | |||
| @@ -32,18 +32,8 @@ module LaboratoryHelper | |||
| end | |||
| def default_course_links | |||
| # my_projects: "/users/#{current_user.try(:login)}/projects", | |||
| # my_projects: "https://www.trustie.net/users/#{current_user.try(:login)}/user_projectlist", | |||
| { | |||
| new_syllabuses: "https://www.trustie.net/syllabuses/new", | |||
| new_course: "https://www.trustie.net/courses/new", | |||
| edit_account: "https://www.trustie.net/my/account", | |||
| my_courses: "https://www.trustie.net/users/#{current_user.try(:login)}/user_courselist", | |||
| my_projects: "/users/#{current_user.try(:login)}/projects", | |||
| my_organ: "https://www.trustie.net/users/#{current_user.try(:login)}/user_organizations", | |||
| default_url: Rails.application.config_for(:configuration)['platform_url'], | |||
| tiding_url: "https://www.trustie.net/users/#{current_user.try(:login)}/user_messages", | |||
| register_url: "https://www.trustie.net/login?login=false" | |||
| default_url: Rails.application.config_for(:configuration)['platform_url'] | |||
| } | |||
| end | |||
| end | |||
| @@ -0,0 +1,17 @@ | |||
| class HomeController < ApplicationController | |||
| def index | |||
| @user_count = Rails.cache.fetch("homecontroller:user_count", expires_in: 1.hours) do | |||
| User.count | |||
| end | |||
| @project_count = Rails.cache.fetch("homecontroller:project_count", expires_in: 1.hours) do | |||
| Project.count | |||
| end | |||
| @project_dataset_count = Rails.cache.fetch("homecontroller:project_dataset_count", expires_in: 1.hours) do | |||
| ProjectDataset.count | |||
| end | |||
| @commit_count = Rails.cache.fetch("homecontroller:commit_count", expires_in: 1.hours) do | |||
| CommitLog.count | |||
| end | |||
| end | |||
| end | |||
| @@ -4,4 +4,8 @@ class LicensesController < ApplicationController | |||
| q = License.ransack(name_cont: params[:name]) | |||
| @licenses = q.result(distinct: true) | |||
| end | |||
| def show | |||
| @license = License.find(params[:id]) | |||
| end | |||
| end | |||
| @@ -140,7 +140,7 @@ class Organizations::OrganizationsController < Organizations::BaseController | |||
| end | |||
| def password | |||
| decrypt(params[:password]) rescue "" | |||
| decrypt(params[:password]) rescue params[:password].to_s | |||
| end | |||
| def load_organization | |||
| @@ -14,6 +14,8 @@ class RepositoriesController < ApplicationController | |||
| before_action :get_latest_commit, only: %i[entries sub_entries top_counts] | |||
| before_action :get_statistics, only: %i[top_counts] | |||
| before_action :require_referer, only: [:raw] | |||
| # before_action :request_limit, only: [:raw] | |||
| before_action :request_raw_limit, only: [:raw] | |||
| def files | |||
| result = @project.educoder? ? nil : Gitea::Repository::Files::GetService.call(@owner, @project.identifier, @ref, params[:search], @owner.gitea_token) | |||
| @@ -35,6 +37,10 @@ class RepositoriesController < ApplicationController | |||
| @fork_project = Project.find_by(id: @project_fork_id) | |||
| @fork_project_user = @fork_project.owner | |||
| end | |||
| # 修正默认分支 | |||
| if @result[:repo].present? && @result[:repo]['default_branch'].present? && @result[:repo]['default_branch'] != @project.default_branch | |||
| @project.update_column('default_branch', @result[:repo]['default_branch']) | |||
| end | |||
| rescue Exception => e | |||
| uid_logger_error(e.message) | |||
| tip_exception(e.message) | |||
| @@ -298,7 +304,7 @@ class RepositoriesController < ApplicationController | |||
| redirect_to file_path | |||
| end | |||
| def raw | |||
| def raw | |||
| domain = GiteaService.gitea_config[:domain] | |||
| api_url = GiteaService.gitea_config[:base_url] | |||
| @@ -1,13 +1,12 @@ | |||
| class SettingsController < ApplicationController | |||
| def show | |||
| @old_projects_url = nil | |||
| get_navbar | |||
| site_page_deploy_domain | |||
| get_add_menu | |||
| get_common_menu | |||
| get_sub_competitions | |||
| get_personal_menu | |||
| get_third_party | |||
| # get_third_party | |||
| get_third_party_new | |||
| get_top_system_notification | |||
| end | |||
| @@ -10,6 +10,8 @@ class Users::MessagesController < Users::BaseController | |||
| result = Notice::Read::ListService.call(observed_user.id, message_type, message_status, page, limit) | |||
| return render_error if result.nil? | |||
| @data = result[2] | |||
| rescue | |||
| render_ok | |||
| end | |||
| def create | |||
| @@ -263,7 +263,7 @@ class UsersController < ApplicationController | |||
| begin | |||
| @user = current_user | |||
| begin | |||
| result = Notice::Read::CountService.call(current_user.id) | |||
| result = EduSetting.get("notice_disable").to_s == "true" ? nil : Notice::Read::CountService.call(current_user.id) | |||
| @message_unread_total = result.nil? ? 0 : result[2]["unread_notification"] | |||
| rescue | |||
| @message_unread_total = 0 | |||
| @@ -54,14 +54,14 @@ class BaseForm | |||
| end | |||
| def check_password(password) | |||
| password = decrypt(password) rescue "" | |||
| password = decrypt(password) rescue password | |||
| password = strip(password) | |||
| raise PasswordFormatError, "密码8~16位密码,支持字母数字和符号" unless password =~ CustomRegexp::PASSWORD | |||
| end | |||
| def check_password_confirmation(password, password_confirmation) | |||
| password = decrypt(password) rescue "" | |||
| password_confirmation = decrypt(password_confirmation) rescue "" | |||
| password = decrypt(password) rescue password | |||
| password_confirmation = decrypt(password_confirmation) rescue password_confirmation | |||
| password = strip(password) | |||
| password_confirmation = strip(password_confirmation) | |||
| @@ -161,6 +161,7 @@ module RepositoriesHelper | |||
| 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] | |||
| next if s_content.blank? | |||
| # content = content.gsub(s[0], "/#{s_content}") | |||
| join_xxx = s_content.include?("?") ? "&" : "?" | |||
| s_content = [base_url, "/api/#{owner&.login}/#{repo.identifier}/raw/#{s_content}#{join_xxx}ref=#{ref}"].join | |||
| @@ -190,6 +191,7 @@ module RepositoriesHelper | |||
| path = [owner&.login, repo&.identifier, 'tree', ref, file_path].join("/") | |||
| s_content = File.expand_path(s_content, path) | |||
| s_content = s_content.split("#{Rails.root}")[1] | |||
| next if s_content.blank? | |||
| case k.to_s | |||
| when 'ss_src' | |||
| content = content.gsub("src=\"#{s[0]}\"", "src=\"/#{s_content}\"") | |||
| @@ -202,7 +204,7 @@ module RepositoriesHelper | |||
| when 'ss_href_1' | |||
| content = content.gsub("href=\'#{s[0]}\'", "href=\'#{s_content}\'") | |||
| else | |||
| content = content.gsub("(#{s[0]})", "(/#{s_content})") | |||
| content = content.gsub("(#{s[0]})", "(#{s_content})") | |||
| end | |||
| end | |||
| rescue | |||
| @@ -8,7 +8,8 @@ class TouchWebhookJob < ApplicationJob | |||
| issue = Issue.find_by_id issue_id | |||
| sender = User.find_by_id sender_id | |||
| return if issue.nil? || sender.nil? | |||
| issue.project.webhooks.each do |webhook| | |||
| return if issue.project.nil? | |||
| issue.project.webhooks.each do |webhook| | |||
| next unless webhook.events["events"]["issues"] | |||
| _, _, @webhook_task = Webhook::IssueClient.new(webhook, issue, sender,"issues").do_request | |||
| Rails.logger.info "Touch Webhook Response result: #{@webhook_task.response_content}" | |||
| @@ -18,6 +19,7 @@ class TouchWebhookJob < ApplicationJob | |||
| issue = Issue.find_by_id issue_id | |||
| sender = User.find_by_id sender_id | |||
| return if issue.nil? || sender.nil? || !changes.is_a?(Hash) || changes.blank? | |||
| return if issue.project.nil? | |||
| issue.project.webhooks.each do |webhook| | |||
| next unless webhook.events["events"]["issues"] | |||
| _, _, @webhook_task = Webhook::IssueClient.new(webhook, issue, sender, "issues", changes.stringify_keys).do_request | |||
| @@ -29,6 +31,7 @@ class TouchWebhookJob < ApplicationJob | |||
| issue = Issue.find_by_id issue_id | |||
| sender = User.find_by_id sender_id | |||
| return if issue.nil? || sender.nil? | |||
| return if issue.project.nil? | |||
| issue.project.webhooks.each do |webhook| | |||
| next unless webhook.events["events"]["issue_assign"] | |||
| _, _, @webhook_task = Webhook::IssueClient.new(webhook, issue, sender, "issue_assign", changes.stringify_keys).do_request | |||
| @@ -39,7 +42,8 @@ class TouchWebhookJob < ApplicationJob | |||
| issue_id, sender_id, changes = args[0], args[1], args[2] | |||
| issue = Issue.find_by_id issue_id | |||
| sender = User.find_by_id sender_id | |||
| return if issue.nil? || sender.nil? | |||
| return if issue.nil? || sender.nil? | |||
| return if issue.project.nil? | |||
| issue.project.webhooks.each do |webhook| | |||
| next unless webhook.events["events"]["issue_label"] | |||
| _, _, @webhook_task = Webhook::IssueClient.new(webhook, issue, sender, "issue_label", changes.stringify_keys).do_request | |||
| @@ -53,6 +57,7 @@ class TouchWebhookJob < ApplicationJob | |||
| return if issue.nil? || sender.nil? | |||
| comment = issue.comment_journals.find_by_id comment_id | |||
| return if action_type == 'edited' && comment_json.blank? | |||
| return if issue.project.nil? | |||
| issue.project.webhooks.each do |webhook| | |||
| next unless webhook.events["events"]["issue_comment"] | |||
| @@ -68,6 +73,7 @@ class TouchWebhookJob < ApplicationJob | |||
| return if issue.nil? || pull.nil? || sender.nil? | |||
| comment = issue.comment_journals.find_by_id comment_id | |||
| return if action_type == 'edited' && comment_json.blank? | |||
| return if issue.project.nil? | |||
| pull.project.webhooks.each do |webhook| | |||
| next unless webhook.events["events"]["pull_request_comment"] | |||
| @@ -0,0 +1,44 @@ | |||
| module SonarService | |||
| def build_sonar_content(owner,project_id,lang_keys) | |||
| lang_map = { | |||
| 'Java' => :java, | |||
| 'Python' => :python, | |||
| 'JavaScript' => :js, | |||
| 'TypeScript' => :ts, | |||
| 'C++' => :cpp, | |||
| 'C' => :cpp | |||
| } | |||
| detected_langs = lang_keys.map { |l| lang_map[l] }.compact.to_set | |||
| 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__/**" | |||
| if detected_langs.include?(:java) | |||
| lines << "sonar.java.binaries=" | |||
| end | |||
| if detected_langs.include?(:js) | |||
| lines << "sonar.javascript.lcov.reportPaths=coverage/lcov.info" | |||
| end | |||
| if detected_langs.include?(:ts) | |||
| lines << "sonar.typescript.tsconfigPath=tsconfig.json" | |||
| end | |||
| if detected_langs.include?(:python) | |||
| 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" | |||
| end | |||
| lines.join("\n") | |||
| end | |||
| end | |||
| @@ -33,7 +33,7 @@ class Action::Pipeline < ApplicationRecord | |||
| belongs_to :user, optional: true | |||
| belongs_to :project | |||
| validates :name, presence: { message: "不能为空" } | |||
| validates :pipeline_name, presence: { message: "不能为空" } | |||
| validates :json, length: { maximum: 65535, too_long: "不能超过65535个字符"} | |||
| validates :yaml, length: { maximum: 65535, too_long: "不能超过65535个字符"} | |||
| end | |||
| @@ -24,7 +24,7 @@ | |||
| class CommitLog < ApplicationRecord | |||
| belongs_to :user | |||
| belongs_to :project | |||
| belongs_to :repository | |||
| # belongs_to :repository | |||
| has_many :project_trends, as: :trend, dependent: :destroy | |||
| @@ -0,0 +1,9 @@ | |||
| class Gitea::RepoUnit < Gitea::Base | |||
| self.inheritance_column = nil # FIX The single-table inheritance mechanism failed | |||
| # establish_connection :gitea_db | |||
| self.table_name = "repo_unit" | |||
| # belongs_to :user, class_name: '::User', primary_key: :gitea_uid, foreign_key: :owner_id, optional: true | |||
| end | |||
| @@ -298,6 +298,38 @@ class Issue < ApplicationRecord | |||
| self.project.decrement!(:closed_issues_count) if self.status_id == 5 && self.project.present? | |||
| end | |||
| # def self.find_issues_by_pm(enterprise_identifier, pm_issue_type) | |||
| # case pm_issue_type.to_i | |||
| # when 1 | |||
| # Issue.issue_issue.where(enterprise_identifier: enterprise_identifier) | |||
| # .where(pm_issue_type: pm_issue_type) | |||
| # .where(pm_issue_type_index1: index) | |||
| # when 2 | |||
| # Issue.issue_issue.where(enterprise_identifier: enterprise_identifier) | |||
| # .where(pm_issue_type: pm_issue_type) | |||
| # .where(pm_issue_type_index2: index) | |||
| # when 3 | |||
| # Issue.issue_issue.where(enterprise_identifier: enterprise_identifier) | |||
| # .where(pm_issue_type: pm_issue_type) | |||
| # .where(pm_issue_type_index3: index) | |||
| # end | |||
| # end | |||
| # | |||
| # def self.build_pm_index(enterprise_identifier, pm_issue_type) | |||
| # last_issue = Issue.find_issues_by_pm(enterprise_identifier, pm_issue_type).order("pm_issue_type_index#{pm_issue_type.to_i} asc").last | |||
| # deleted_issue_count = ($redis_cache.hget("pm_issue_cache_delete_count", enterprise_identifier) || 0).to_i | |||
| # | |||
| # last_issue.send("pm_issue_type_index#{pm_issue_type.to_i}").present? ? last_issue.send("pm_issue_type_index#{pm_issue_type.to_i}") + deleted_issue_count : 0 | |||
| # end | |||
| # | |||
| # def incre_pm_issue_cache_delete_count(count=1) | |||
| # $redis_cache.hincrby("pm_issue_cache_delete_count", self.enterprise_identifier, count) | |||
| # end | |||
| # | |||
| # def del_pm_issue_cache_delete_count | |||
| # $redis_cache.hdel("pm_issue_cache_delete_count", self.enterprise_identifier) | |||
| # end | |||
| def send_update_message_to_notice_system | |||
| SendTemplateMessageJob.perform_later('IssueExpire', self.id) if Site.has_notice_menu? && self.due_date == Date.today + 1.days | |||
| end | |||
| @@ -453,7 +453,7 @@ class Project < ApplicationRecord | |||
| end | |||
| def get_last_project_issues_index | |||
| last_issue = self.issues.issue_issue.last | |||
| last_issue = self.issues.issue_issue.order(project_issues_index: :asc).last | |||
| deleted_issue_count = ($redis_cache.hget("issue_cache_delete_count", self.id) || 0).to_i | |||
| last_issue&.project_issues_index.present? ? last_issue.project_issues_index + deleted_issue_count : 0 | |||
| @@ -23,7 +23,7 @@ class ProjectUnit < ApplicationRecord | |||
| def self.init_types(project_id, project_type='common') | |||
| unit_types = project_type == 'sync_mirror' ? ProjectUnit::unit_types.except("pulls") : ProjectUnit::unit_types | |||
| unit_types = unit_types.except("dataset") | |||
| unit_types = unit_types.except("dataset") unless EduSetting.get("is_local") == "true" | |||
| unit_types.each do |_, v| | |||
| self.create!(project_id: project_id, unit_type: v) | |||
| end | |||
| @@ -20,7 +20,8 @@ class Projects::ListMyQuery < ApplicationQuery | |||
| if params[:category].blank? | |||
| normal_projects = projects.members_projects(user.id).to_sql | |||
| org_projects = projects.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 | |||
| watched_projects = projects.where.not(user_id: user.id).joins(:watchers).where(watchers: {watchable_type: "Project", user_id: user.id}).to_sql | |||
| projects = Project.from("( #{ normal_projects} UNION #{ org_projects } UNION #{ watched_projects } ) AS projects")#.distinct | |||
| elsif params[:category].to_s == "join" | |||
| normal_projects = projects.where.not(user_id: user.id).members_projects(user.id).to_sql | |||
| org_projects = projects.joins(team_projects: [team: :team_users]).where(team_users: {user_id: user.id}).to_sql | |||
| @@ -4,8 +4,8 @@ module Accounts | |||
| # login、code、password、password_confirmation | |||
| def initialize(user, params) | |||
| @user = user | |||
| @password = decrypt(params[:password]) rescue "" | |||
| @password_confirmation = decrypt(params[:password_confirmation]) rescue "" | |||
| @password = decrypt(params[:password]) rescue params[:password].to_s | |||
| @password_confirmation = decrypt(params[:password_confirmation]) rescue params[:password_confirmation].to_s | |||
| end | |||
| def call | |||
| @@ -5,7 +5,7 @@ class Api::Pm::Issues::CreateService < ApplicationService | |||
| attr_reader :project, :current_user | |||
| attr_reader :status_id, :priority_id, :milestone_id, :branch_name, :start_date, :due_date, :subject, :description, :blockchain_token_num, :root_subject | |||
| attr_reader :issue_tag_ids, :assigner_ids, :attachment_ids, :receivers_login | |||
| attr_reader :issue_tag_ids, :assigner_ids, :attachment_ids, :receivers_login, :enterprise_identifier, :pm_issue_type | |||
| attr_accessor :created_issue | |||
| validates :subject, presence: true | |||
| @@ -36,6 +36,7 @@ class Api::Pm::Issues::CreateService < ApplicationService | |||
| @time_scale = params[:time_scale] | |||
| @linkable_id = params[:link_able_id] | |||
| @root_subject = params[:root_subject] | |||
| @enterprise_identifier = params[:enterprise_identifier] | |||
| end | |||
| def call | |||
| @@ -56,10 +57,10 @@ class Api::Pm::Issues::CreateService < ApplicationService | |||
| try_lock("Api::Pm::Issues::CreateService:#{project.id}") # 开始写数据,加锁 | |||
| @created_issue = Issue.new(issue_attributes) | |||
| @created_issue.pm_issue_type = @pm_issue_type | |||
| if @root_subject.present? && @pm_issue_type.to_i == 4 | |||
| @root_issue = Issue.find_by(subject: @root_subject, pm_issue_type: 4, pm_project_id: @pm_project_id) | |||
| if @root_subject.present? && [4, 5].include?(@pm_issue_type.to_i) | |||
| @root_issue = Issue.find_by(subject: @root_subject, pm_issue_type: [4,5], pm_project_id: @pm_project_id,enterprise_identifier: @enterprise_identifier) | |||
| unless @root_issue.present? | |||
| @root_issue = Issue.create(subject: @root_subject, pm_issue_type: 4, pm_project_id: @pm_project_id, status_id: 1, priority_id: 1, tracker_id: Tracker.first.id, project_id: @project.id, author_id: current_user.id) | |||
| @root_issue = Issue.create(subject: @root_subject, pm_issue_type: @pm_issue_type.to_i, pm_project_id: @pm_project_id, enterprise_identifier: @enterprise_identifier, status_id: 1, priority_id: 1, tracker_id: Tracker.first.id, project_id: @project.id, author_id: current_user.id) | |||
| end | |||
| @created_issue.root_id = @root_issue.id | |||
| else | |||
| @@ -74,6 +75,7 @@ class Api::Pm::Issues::CreateService < ApplicationService | |||
| @created_issue.attachments = @attachments unless attachment_ids.blank? | |||
| @created_issue.issue_tags = @issue_tags unless issue_tag_ids.blank? | |||
| @created_issue.pm_project_id = @pm_project_id | |||
| @created_issue.enterprise_identifier = @enterprise_identifier | |||
| @created_issue.pm_sprint_id = @pm_sprint_id | |||
| @created_issue.time_scale = @time_scale | |||
| @created_issue.issue_tags_value = @issue_tags.order('id asc').pluck(:id).join(',') unless issue_tag_ids.blank? | |||
| @@ -4,7 +4,7 @@ class Api::Pm::Issues::UpdateService < ApplicationService | |||
| include Api::V1::Issues::Concerns::Loadable | |||
| attr_reader :project, :issue, :current_user, :operate_by | |||
| attr_reader :status_id, :priority_id, :milestone_id, :branch_name, :start_date, :due_date, :subject, :description, :blockchain_token_num | |||
| attr_reader :status_id, :priority_id, :milestone_id, :branch_name, :start_date, :due_date, :subject, :description, :blockchain_token_num,:status_msg | |||
| attr_reader :target_pm_project_id, :pm_sprint_id, :pm_issue_type, :root_id, :time_scale | |||
| attr_reader :issue_tag_ids, :assigner_ids, :attachment_ids, :receivers_login, :before_issue_tag_ids, :before_assigner_ids, :project_id | |||
| attr_accessor :add_assigner_ids, :previous_issue_changes, :updated_issue, :atme_receivers | |||
| @@ -18,6 +18,7 @@ class Api::Pm::Issues::UpdateService < ApplicationService | |||
| @current_user = current_user | |||
| @operate_by = operate_by | |||
| @status_id = params[:status_id] | |||
| @status_msg = params[:status_msg] | |||
| @priority_id = params[:priority_id] | |||
| @milestone_id = params[:milestone_id] | |||
| @branch_name = params[:branch_name] | |||
| @@ -85,6 +86,10 @@ class Api::Pm::Issues::UpdateService < ApplicationService | |||
| @updated_issue.root_id = @root_id unless @root_id.nil? #不为 nil的时候更新 | |||
| @updated_issue.root_id = nil if @root_id.try(:zero?) #为 0 的时候设置为 nil | |||
| @updated_issue.time_scale = @time_scale unless @time_scale.nil? | |||
| if @project_id.present? && @updated_issue.project_id.to_i == 0 | |||
| add_project = Project.find_by(id: @project_id) | |||
| @updated_issue.project_issues_index = add_project.get_last_project_issues_index + 1 if add_project.present? | |||
| end | |||
| @updated_issue.project_id = @project_id unless @project_id.nil? | |||
| @updated_issue.updated_on = Time.now | |||
| @updated_issue.changer_id = @current_user.id | |||
| @@ -197,7 +202,12 @@ class Api::Pm::Issues::UpdateService < ApplicationService | |||
| # 修改状态 | |||
| if @updated_issue.previous_changes["status_id"].present? | |||
| journal = @updated_issue.journals.create!({user_id: current_user.id, operate_by: @operate_by}) | |||
| journal.journal_details.create!({property: @updated_issue.pm_issue_type_string, prop_key: "status_id", old_value: @updated_issue.previous_changes["status_id"][0], value: @updated_issue.previous_changes["status_id"][1]}) | |||
| journal.journal_details.create!({property: @updated_issue.pm_issue_type_string, | |||
| prop_key: "status_id", | |||
| status_msg: @status_msg, | |||
| old_value: @updated_issue.previous_changes["status_id"][0], | |||
| value: @updated_issue.previous_changes["status_id"][1]} | |||
| ) | |||
| end | |||
| # 修改优先级 | |||
| @@ -3,7 +3,7 @@ class Api::V1::Issues::ListService < ApplicationService | |||
| attr_reader :project, :only_name, :category, :participant_category, :keyword, :author_id, :issue_tag_ids | |||
| attr_reader :begin_date, :end_date, :update_begin_date, :update_end_date | |||
| attr_reader :milestone_id, :assigner_id, :status_id, :priority_id, :sort_by, :sort_direction, :current_user | |||
| attr_reader :milestone_id, :assigner_id, :status_id, :priority_id, :sort_by, :sort_direction, :current_user, :enterprise_identifier | |||
| attr_reader :pm_project_id, :pm_project_ids, :pm_sprint_id, :root_id, :pm_issue_type, :status_ids, :ids, :exclude_ids, :pm_issue_types | |||
| attr_accessor :queried_issues, :total_issues_count, :closed_issues_count, :opened_issues_count, :complete_issues_count, :participator | |||
| @@ -30,6 +30,7 @@ class Api::V1::Issues::ListService < ApplicationService | |||
| @update_begin_date = params[:update_begin_date] | |||
| @update_end_date = params[:update_end_date] | |||
| @sort_by = params[:sort_by].present? ? params[:sort_by] : 'issues.updated_on' | |||
| @enterprise_identifier = params[:enterprise_identifier] | |||
| @pm_project_id = params[:pm_project_id] | |||
| @pm_project_ids = params[:pm_project_ids] | |||
| @pm_sprint_id = params[:pm_sprint_id] | |||
| @@ -96,6 +97,8 @@ class Api::V1::Issues::ListService < ApplicationService | |||
| end | |||
| end | |||
| issues = issues.where(enterprise_identifier: enterprise_identifier) if enterprise_identifier.present? && ([4,5].include?(pm_issue_type.to_i) || pm_issue_types.present?) | |||
| #pm相关 | |||
| # root_id# -1 查一级目录 | |||
| issues = if root_id.to_i == -1 | |||
| @@ -148,7 +151,7 @@ class Api::V1::Issues::ListService < ApplicationService | |||
| end | |||
| if update_begin_date&.present? || update_end_date&.present? | |||
| issues = issues.where('issues.updated_on between ? and ?', update_begin_date&.present? ? update_begin_date.to_time : Time.now.beginning_of_day, update_end_date&.present? ? update_end_date.to_time.end_of_day : Time.now.end_of_day) | |||
| issues = issues.where('issues.updated_on between ? and ?', update_begin_date&.present? ? update_begin_date.to_time.beginning_of_week : Time.now.beginning_of_week, update_end_date&.present? ? update_end_date.to_time.end_of_week : Time.now.end_of_week) | |||
| end | |||
| # keyword | |||
| @@ -85,9 +85,14 @@ class Api::V1::Issues::UpdateService < ApplicationService | |||
| @updated_issue.root_id = @root_id unless @root_id.nil? #不为 nil的时候更新 | |||
| @updated_issue.root_id = nil if @root_id.try(:zero?) #为 0 的时候设置为 nil | |||
| @updated_issue.time_scale = @time_scale unless @time_scale.nil? | |||
| if @project_id.present? && @updated_issue.project_id.to_i == 0 | |||
| add_project = Project.find_by(id: @project_id) | |||
| @updated_issue.project_issues_index = add_project.get_last_project_issues_index + 1 if add_project.present? | |||
| end | |||
| @updated_issue.project_id = @project_id unless @project_id.nil? | |||
| @updated_issue.updated_on = Time.now | |||
| @updated_issue.changer_id = @current_user.id | |||
| @updated_issue.due_date = Time.now if @updated_issue.status_id == 5 && @due_date.blank? | |||
| @updated_issue.save! | |||
| build_after_issue_journal_details if @updated_issue.previous_changes.present? # 操作记录 | |||
| @@ -23,8 +23,8 @@ class Api::V1::Users::DeleteUserService < ApplicationService | |||
| end | |||
| @user.destroy! | |||
| del_user_data_by_sql(@user.id) | |||
| Gitea::User::DeleteService.call(@user.login, true) | |||
| end | |||
| Gitea::User::DeleteService.call(@user.login, true) | |||
| return true | |||
| rescue | |||
| raise Error, "服务器错误,请联系系统管理员!" | |||
| @@ -32,7 +32,11 @@ class Api::V1::Users::DeleteUserService < ApplicationService | |||
| end | |||
| def del_user_data_by_sql(user_id) | |||
| sql1 = "delete from memos where author_id=#{user_id}" | |||
| ActiveRecord::Base.connection.execute(sql1) | |||
| if ActiveRecord::Base.connection.table_exists?("memos") | |||
| sql1 = "delete from memos where author_id=#{user_id}" | |||
| ActiveRecord::Base.connection.execute(sql1) | |||
| else | |||
| Rails.logger.info "memos table does not exist" | |||
| end | |||
| end | |||
| end | |||
| @@ -11,7 +11,7 @@ class Api::V1::Users::UpdateEmailService < ApplicationService | |||
| def initialize(user, params, token =nil) | |||
| @user = user | |||
| @token = token | |||
| @password = decrypt(params[:password]) rescue "" | |||
| @password = decrypt(params[:password]) rescue params[:password].to_s | |||
| @mail = params[:email] | |||
| @old_mail = user.mail | |||
| @code = params[:code] | |||
| @@ -9,7 +9,7 @@ class Api::V1::Users::UpdatePhoneService < ApplicationService | |||
| def initialize(user, params) | |||
| @user = user | |||
| @password = decrypt(params[:password]) rescue "" | |||
| @password = decrypt(params[:password]) rescue params[:password].to_s | |||
| @phone = params[:phone] | |||
| @code = params[:code] | |||
| @verify_code = VerificationCode.where(phone: @phone, code_type: 4).last | |||
| @@ -56,6 +56,11 @@ class Cache::V2::PlatformStatisticService < ApplicationService | |||
| "max-issue-count" | |||
| end | |||
| # 平台最高已解决issue数 | |||
| def max_complete_issue_count_key | |||
| "max-complete-issue-count" | |||
| end | |||
| # 平台最高commit数 | |||
| def max_commit_count_key | |||
| "max-commit-count" | |||
| @@ -86,6 +91,11 @@ class Cache::V2::PlatformStatisticService < ApplicationService | |||
| "max-recent-one-month-commit-count" | |||
| end | |||
| # 平台近一个月release最大值 | |||
| def max_recent_one_month_release_count_key | |||
| "max-recent-one-month-release-count" | |||
| end | |||
| def follow_count_key | |||
| "follow-count" | |||
| end | |||
| @@ -216,6 +226,11 @@ class Cache::V2::PlatformStatisticService < ApplicationService | |||
| $redis_cache.hset(platform_statistic_key, max_issue_count_key, max_issue[1].nil? ? 0 : max_issue[1]) | |||
| end | |||
| def reset_platform_max_complete_issue_count | |||
| max_complete_issue = Issue.where.not(project_id: 0).issue_issue.where(status_id: [3,5]).group(:project_id).count.sort_by{|i|i[1]}.last || [] | |||
| $redis_cache.hset(platform_statistic_key, max_complete_issue_count_key, max_complete_issue[1].nil? ? 0 : max_complete_issue[1]) | |||
| end | |||
| def reset_platform_max_commit_count | |||
| max_commit = CommitLog.joins(:project).merge(Project.common).group(:project_id).count.sort_by{|i|i[1]}.last || [] | |||
| $redis_cache.hset(platform_statistic_key, max_commit_count_key, max_commit[1].nil? ? 0 : max_commit[1]) | |||
| @@ -237,7 +252,7 @@ class Cache::V2::PlatformStatisticService < ApplicationService | |||
| end | |||
| def reset_platform_max_recent_one_month_issue_count | |||
| max_recent_one_month_issue = Issue.issue_issue.where("created_on > ?", Time.now - 30.days).group(:project_id).count.sort_by{|i|i[1]}.last || [] | |||
| max_recent_one_month_issue = Issue.where.not(project_id: 0).issue_issue.where("created_on > ?", Time.now - 30.days).group(:project_id).count.sort_by{|i|i[1]}.last || [] | |||
| $redis_cache.hset(platform_statistic_key, max_recent_one_month_issue_count_key, max_recent_one_month_issue[1].nil? ? 0 : max_recent_one_month_issue[1]) | |||
| end | |||
| @@ -246,6 +261,11 @@ class Cache::V2::PlatformStatisticService < ApplicationService | |||
| $redis_cache.hset(platform_statistic_key, max_recent_one_month_commit_count_key, max_recent_one_month_commit[1].nil? ? 0 : max_recent_one_month_commit[1]) | |||
| end | |||
| def reset_platform_max_recent_one_month_release_count | |||
| max_recent_one_month_release = VersionRelease.where("created_at >?", Time.now - 30.days).group(:repository_id).count.sort_by{|i|i[1]}.last || [] | |||
| $redis_cache.hset(platform_statistic_key, max_recent_one_month_release_count_key, max_recent_one_month_release[1].nil? ? 0 : max_recent_one_month_release[1]) | |||
| end | |||
| def reset_platform_follow_count | |||
| $redis_cache.hset(platform_statistic_key, follow_count_key, Watcher.where(watchable_type: 'User').count) | |||
| end | |||
| @@ -255,7 +275,7 @@ class Cache::V2::PlatformStatisticService < ApplicationService | |||
| end | |||
| def reset_platform_issue_count | |||
| $redis_cache.hset(platform_statistic_key, issue_count_key, Issue.count) | |||
| $redis_cache.hset(platform_statistic_key, issue_count_key, Issue.where.not(project_id: 0).count) | |||
| end | |||
| def reset_platform_project_count | |||
| @@ -299,6 +319,8 @@ class Cache::V2::PlatformStatisticService < ApplicationService | |||
| reset_platform_max_recent_one_month_pullrequest_count | |||
| reset_platform_max_recent_one_month_issue_count | |||
| reset_platform_max_recent_one_month_commit_count | |||
| reset_platform_max_recent_one_month_release_count | |||
| reset_platform_max_complete_issue_count | |||
| $redis_cache.hgetall(platform_statistic_key) | |||
| end | |||
| @@ -4,7 +4,7 @@ class Users::RegisterService < ApplicationService | |||
| def initialize(params) | |||
| @login = params[:login] | |||
| @namespace = params[:namespace] | |||
| @password = decrypt(params[:password]) rescue "" | |||
| @password = decrypt(params[:password]) rescue params[:password].to_s | |||
| @code = params[:code] | |||
| end | |||
| @@ -23,6 +23,10 @@ | |||
| <%= form.label :description, "描述" %> | |||
| <%= form.text_area :description, rows: 5, :style => 'width:800px;' %> | |||
| </div> | |||
| <div class="field"> | |||
| <%= form.label :default_value, "默认值" %> | |||
| <%= form.text_field :default_value %> | |||
| </div> | |||
| <div class="field"> | |||
| <%= form.label :is_required, "是否必填项" %> | |||
| <%= form.check_box("is_required", {}, "true", "false") %> | |||
| @@ -1,4 +1,4 @@ | |||
| json.extract! node_input, :id, :name, :input_type, :description | |||
| json.extract! node_input, :id, :name, :input_type, :description, :is_required, :default_value | |||
| if node_input.input_type.to_s == "select" | |||
| json.select node.action_node_selects do |node_select| | |||
| json.partial! "node_select", locals: { node_select: node_select, node: node } | |||
| @@ -27,6 +27,10 @@ | |||
| <%= form.label :description, "描述" %> | |||
| <%= form.text_area :description, rows: 5, :style => 'width:800px;' %> | |||
| </div> | |||
| <div class="field"> | |||
| <%= form.label :default_value, "默认值" %> | |||
| <%= form.text_field :default_value %> | |||
| </div> | |||
| <div class="field"> | |||
| <%= form.label :is_required, "是否必填项" %> | |||
| <%= form.check_box("is_required", {}, "true", "false") %> | |||
| @@ -1,4 +1,4 @@ | |||
| json.extract! node_input, :id, :name, :input_type, :description, :is_required | |||
| json.extract! node_input, :id, :name, :input_type, :description, :is_required, :default_value | |||
| if node_input.input_type.to_s == "select" | |||
| json.select node.action_node_selects do |node_select| | |||
| json.partial! "node_select", locals: { node_select: node_select, node: node } | |||
| @@ -51,7 +51,7 @@ | |||
| <li> | |||
| <%= sidebar_item_group('#setting-index', '首页配置', icon: 'file', has_permission: current_user.admin? || current_user.business?) do %> | |||
| <li><%= sidebar_item(admins_topic_banners_path, 'banner管理', icon: 'image', controller: 'admins-topic-banners', has_permission: current_user.admin? || current_user.business?) %></li> | |||
| <!--<li><%#= sidebar_item(admins_topic_cards_path, '卡片管理', icon: 'archive', controller: 'admins-topic-cards', has_permission: current_user.admin? || current_user.business?) %></li>--> | |||
| <li><%= sidebar_item(admins_topic_cards_path, '卡片管理', icon: 'archive', controller: 'admins-topic-cards', has_permission: current_user.admin? || current_user.business?) %></li> | |||
| <li><%= sidebar_item(admins_topic_activity_forums_path, '平台动态管理', icon: 'bell', controller: 'admins-topic-activity_forums', has_permission: current_user.admin? || current_user.business?) %></li> | |||
| <li><%= sidebar_item(admins_topic_excellent_projects_path, '优秀仓库管理', icon: 'git', controller: 'admins-topic-excellent_projects', has_permission: current_user.admin? || current_user.business?) %></li> | |||
| <li><%= sidebar_item(admins_topic_pinned_forums_path, '精选文章管理', icon: 'edit', controller: 'admins-topic-pinned_forums', has_permission: current_user.admin? || current_user.business?) %></li> | |||
| @@ -30,7 +30,7 @@ | |||
| <li><%= sidebar_item(admins_project_ignores_path, '忽略文件', icon: 'git', controller: 'admins-project_ignores', has_permission: current_user.admin?) %></li> | |||
| <% end %> | |||
| </li> | |||
| <!-- <li><%#= sidebar_item(admins_laboratories_path, '导航栏配置', icon: 'cloud', controller: 'admins-laboratories', has_permission: current_user.admin?) %></li>--> | |||
| <li><%= sidebar_item(admins_laboratories_path, '导航栏配置', icon: 'cloud', controller: 'admins-laboratories', has_permission: current_user.admin?)%></li> | |||
| <li> | |||
| <%= sidebar_item_group('#setting-system', '开发者配置', icon: 'wrench', has_permission: current_user.admin?) do %> | |||
| <li><%= sidebar_item(admins_sites_path, 'setting接口配置', icon: 'deaf', controller: 'admins-sites', has_permission: current_user.admin?) %></li> | |||
| @@ -13,6 +13,7 @@ if journal.is_journal_detail? | |||
| detail = journal.journal_details.take | |||
| json.operate_category journal.pm_operate_category | |||
| json.operate_content journal.is_journal_detail? ? journal.pm_operate_content : nil | |||
| json.status_msg detail.status_msg | |||
| else | |||
| json.notes journal.notes | |||
| json.comments_count journal.comments_count | |||
| @@ -0,0 +1,30 @@ | |||
| json.status 0 | |||
| json.message "success" | |||
| json.count @pipelines.total_count | |||
| json.projects @pipelines.map(&:project_id).uniq.each do |project_id| | |||
| json.id project_id | |||
| project = Project.find_by(id: project_id) | |||
| if project.present? | |||
| json.owner project.owner.name | |||
| json.identifier project.identifier | |||
| json.name project.name | |||
| json.url "#{Rails.application.config_for(:configuration)['platform_url']}/#{project.owner.name}/#{project.identifier}" | |||
| pipelines = Action::Pipeline.where(project_id: project.id).order(updated_at: :desc) | |||
| json.pipelines pipelines.each do |pipeline| | |||
| json.extract! pipeline, :id, :project_id, :pipeline_name, :pipeline_status, :description, :file_name, :is_graphic_design, | |||
| :repo_name, :repo_identifier, :branch, :event, :sha, :disable, :json, :yaml, :created_at, :updated_at | |||
| repo_config = @disabled_workflows.select { |config| config.repo_id == pipeline.project.gpid } | |||
| if repo_config.present? | |||
| json.disable JSON.parse(repo_config.first.config)["DisabledWorkflows"].to_s.include?(pipeline.file_name.to_s.gsub(".gitea/workflows/", "")) | |||
| else | |||
| json.disable pipeline.disable | |||
| end | |||
| json.pipeline_type pipeline.pipeline_type | |||
| if pipeline.json.blank? && pipeline.yaml.blank? | |||
| json.run_data nil | |||
| else | |||
| json.run_data @run_result.select { |result| result[:repo_id] == project.gpid && result[:filename] == pipeline.file_name}.first | |||
| end | |||
| end | |||
| end | |||
| end | |||
| @@ -0,0 +1,4 @@ | |||
| json.total_count @this_week_all_issues.total_count | |||
| json.issues @this_week_all_issues.each do |issue| | |||
| json.partial! "api/v1/issues/simple_detail", locals: {issue: issue} | |||
| end | |||
| @@ -0,0 +1,18 @@ | |||
| json.this_week_all_issues @this_week_all_issues.each do |issue| | |||
| json.partial! "api/v1/issues/simple_detail", locals: {issue: issue} | |||
| end | |||
| json.this_week_total_count @this_week_all_issues.total_count | |||
| json.next_week_all_issues @next_week_all_issues.each do |issue| | |||
| json.partial! "api/v1/issues/simple_detail", locals: {issue: issue} | |||
| end | |||
| json.next_week_total_count @next_week_all_issues.total_count | |||
| json.this_week_requirement_issues_count @this_week_requirement_issues.count | |||
| json.this_week_task_issues_count @this_week_task_issues.count | |||
| json.this_week_bug_issues_count @this_week_bug_issues.count | |||
| json.close_requirement_issues_count @close_requirement_issues.count | |||
| json.close_task_issues_count @close_task_issues.count | |||
| json.close_bug_issues_count @close_bug_issues.count | |||
| json.unclose_count @this_week_all_issues.count - @close_requirement_issues.count - @close_task_issues.count - @close_bug_issues.count | |||
| json.close_task_issues @close_task_issues.each do |issue| | |||
| json.partial! "api/v1/issues/simple_detail", locals: {issue: issue} | |||
| end | |||
| @@ -0,0 +1,8 @@ | |||
| json.this_week_all_issues @this_week_all_issues.each do |issue| | |||
| json.partial! "api/v1/issues/simple_detail", locals: {issue: issue} | |||
| end | |||
| json.this_week_total_count @this_week_all_issues.total_count | |||
| json.next_week_all_issues @next_week_all_issues.each do |issue| | |||
| json.partial! "api/v1/issues/simple_detail", locals: {issue: issue} | |||
| end | |||
| json.next_week_total_count @next_week_all_issues.total_count | |||
| @@ -30,7 +30,11 @@ json.pm_issue_type issue.pm_issue_type | |||
| json.pm_sprint_id issue.pm_sprint_id | |||
| json.pm_project_id issue.pm_project_id | |||
| json.time_scale issue.time_scale | |||
| json.child_count issue.child_count | |||
| if params[:pm_issue_types].present? | |||
| json.child_count issue.children_issues.where(pm_issue_type: 4).count | |||
| else | |||
| json.child_count issue.child_count | |||
| end | |||
| json.author do | |||
| json.partial! "api/v1/users/simple_user", locals: {user: issue.user} | |||
| @@ -1,24 +1,29 @@ | |||
| json.total_data @result_object[:total_data].to_i | |||
| if @result_object[:data]["Runs"].present? | |||
| json.runs @result_object[:data]["Runs"].each_with_index.to_a do |run, index| | |||
| json.num @result_object[:total_data].to_i - @begin_num - index | |||
| json.workflow run["WorkflowID"] | |||
| json.index run["Index"] | |||
| json.title run["Title"] | |||
| json.trigger_user do | |||
| json.partial! 'api/v1/users/commit_user', locals: { user: render_cache_commit_author(run['TriggerUser']), name: run['TriggerUser']['Name'] } | |||
| end | |||
| if @has_file | |||
| json.total_data @result_object[:total_data].to_i | |||
| if @result_object[:data]["Runs"].present? | |||
| json.runs @result_object[:data]["Runs"].each_with_index.to_a do |run, index| | |||
| json.num @result_object[:total_data].to_i - @begin_num - index | |||
| json.workflow run["WorkflowID"] | |||
| json.index run["Index"] | |||
| json.title run["Title"] | |||
| json.trigger_user do | |||
| json.partial! 'api/v1/users/commit_user', locals: { user: render_cache_commit_author(run['TriggerUser']), name: run['TriggerUser']['Name'] } | |||
| end | |||
| if run["Ref"].starts_with?("refs/tags") | |||
| json.ref run["Ref"].gsub!("/refs/tags/", "") | |||
| else | |||
| json.ref run["Ref"].gsub!("refs/heads/", "") | |||
| end | |||
| if run["Ref"].starts_with?("refs/tags") | |||
| json.ref run["Ref"].gsub!("/refs/tags/", "") | |||
| else | |||
| json.ref run["Ref"].gsub!("refs/heads/", "") | |||
| end | |||
| json.status run["Status"] | |||
| json.time_ago time_from_now(run["Created"]) | |||
| json.holding_time run["Status"] == 6 ? Time.now.to_i - run["Created"] : run["Stopped"] - run["Created"] | |||
| json.status run["Status"] | |||
| json.time_ago time_from_now(run["Created"]) | |||
| json.holding_time run["Status"] == 6 ? Time.now.to_i - run["Created"] : run["Stopped"] - run["Created"] | |||
| end | |||
| else | |||
| json.runs [] | |||
| end | |||
| else | |||
| json.runs [] | |||
| json.total_data 0 | |||
| json.runs [] | |||
| end | |||
| @@ -0,0 +1,4 @@ | |||
| json.status 0 | |||
| json.message "success" | |||
| json.extract! @pipeline, :id, :pipeline_name, :pipeline_status, :description, :file_name, :is_graphic_design, :pipeline_type, | |||
| :repo_name, :repo_identifier, :branch, :event, :sha, :disable, :json, :yaml, :created_at, :updated_at | |||
| @@ -1,8 +1,11 @@ | |||
| json.status 0 | |||
| json.message "success" | |||
| json.count @pipelines.total_count | |||
| json.pipelines @pipelines.each do |pip| | |||
| json.extract! pip, :id, :pipeline_name, :pipeline_status, :description, :file_name, :is_graphic_design, | |||
| json.pipelines @pipelines.each do |pipeline| | |||
| json.extract! pipeline, :id, :pipeline_name, :pipeline_status, :description, :file_name, :is_graphic_design, | |||
| :repo_name, :repo_identifier, :branch, :event, :sha, :disable, :json, :yaml, :created_at, :updated_at | |||
| # json.project | |||
| json.disable @disabled_workflows.include?(pipeline.file_name.to_s.gsub(".gitea/workflows/", "")) | |||
| json.pipeline_type pipeline.pipeline_type | |||
| json.run_data @run_result.select { |result| result[:filename] == pipeline.file_name }.first | |||
| end | |||
| @@ -1,5 +1,5 @@ | |||
| json.status 0 | |||
| json.message "success" | |||
| json.extract! @pipeline, :id, :pipeline_name, :pipeline_status, :description, :file_name, :is_graphic_design, | |||
| :repo_name, :repo_identifier, :branch, :event, :sha, :disable, :json, :yaml, :created_at, :updated_at | |||
| # json.project | |||
| json.extract! @pipeline, :id, :pipeline_name, :pipeline_status, :description, :file_name, :is_graphic_design, :pipeline_type, | |||
| :repo_name, :repo_identifier, :branch, :event, :sha, :json, :yaml, :created_at, :updated_at | |||
| json.disable @disabled_workflows.include?(@pipeline.file_name.to_s.gsub(".gitea/workflows/", "")) | |||
| @@ -1,21 +1,9 @@ | |||
| json.images_url @images_url | |||
| json.reps @rep_list | |||
| json.shixuns do | |||
| json.partial! 'shixuns/shixun', locals: {shixuns: @shixuns} | |||
| end | |||
| json.subjects do | |||
| json.partial! 'subjects/subject', locals: {subjects: @subjects} | |||
| json.status 0 | |||
| json.message "success" | |||
| json.statistics_data do | |||
| json.user_count @user_count | |||
| json.project_count @project_count | |||
| json.project_dataset_count @project_dataset_count | |||
| json.commit_count @commit_count | |||
| end | |||
| # if current_laboratory.main_site? | |||
| # json.teachers do | |||
| # json.partial! 'users/user_small', users: @tea_users | |||
| # end | |||
| # | |||
| # json.students do | |||
| # json.partial! 'users/user_small', users: @stu_users | |||
| # end | |||
| # end | |||
| @@ -0,0 +1,3 @@ | |||
| json.id @license.id | |||
| json.name @license.name | |||
| json.content @license.content | |||
| @@ -10,6 +10,7 @@ json.projects @projects do |project| | |||
| json.praises_count project.praises_count.to_i | |||
| json.forked_count project.forked_count.to_i | |||
| json.is_public project.is_public | |||
| json.license_id project.license_id | |||
| json.mirror_url project.repository&.mirror_url | |||
| json.type project&.numerical_for_project_type | |||
| json.last_update_time render_unix_time(project.updated_on) | |||
| @@ -50,7 +51,7 @@ json.projects @projects do |project| | |||
| json.name project.project_language.name | |||
| end | |||
| end | |||
| json.topics project.project_topics.each do |topic| | |||
| json.topics project.project_topics.each do |topic| | |||
| json.(topic, :id, :name) | |||
| end | |||
| end | |||
| @@ -66,6 +66,7 @@ else | |||
| json.private !@project.is_public | |||
| end | |||
| json.license_name @project.license_name | |||
| json.license_id @project.license_id | |||
| json.branches_count @result[:branch_tag_total_count].present? ? (@result[:branch_tag_total_count]['branch_count'] || 0) : 0 | |||
| json.tags_count @result[:branch_tag_total_count].present? ? (@result[:branch_tag_total_count]['tag_count'] || 0) : 0 | |||
| # json.contributors do | |||
| @@ -1,33 +1,4 @@ | |||
| json.setting do | |||
| # if @laboratory.present? | |||
| # setting = @laboratory.laboratory_setting | |||
| # json.name setting.name || default_setting.name | |||
| # json.nav_logo_url (setting.nav_logo_url || default_setting.nav_logo_url)&.[](1..-1) | |||
| # json.login_logo_url (setting.login_logo_url || default_setting.login_logo_url)&.[](1..-1) | |||
| # json.tab_logo_url (setting.tab_logo_url || default_setting.tab_logo_url)&.[](1..-1) | |||
| # | |||
| # json.subject_banner_url (setting.subject_banner_url || default_setting.subject_banner_url)&.[](1..-1) | |||
| # json.course_banner_url (setting.course_banner_url || default_setting.course_banner_url)&.[](1..-1) | |||
| # json.competition_banner_url (setting.competition_banner_url || default_setting.competition_banner_url)&.[](1..-1) | |||
| # json.moop_cases_banner_url (setting.moop_cases_banner_url || default_setting.moop_cases_banner_url)&.[](1..-1) | |||
| # json.oj_banner_url (setting.oj_banner_url || default_setting.oj_banner_url)&.[](1..-1) | |||
| # | |||
| # json.navbar setting.navbar || default_setting.navbar | |||
| # | |||
| # json.footer setting.footer || default_setting.footer | |||
| # | |||
| # end | |||
| # nav_bar = default_setting.navbar | |||
| # if User.current.logged? | |||
| # nav_bar[2]["link"] = "https://forgeplus.trustie.net/users/#{current_user.login}/projects" | |||
| # nav_bar[2]["hidden"] = false | |||
| # else | |||
| # nav_bar[2]["link"] = "" | |||
| # nav_bar[2]["hidden"] = true | |||
| # end | |||
| json.name default_setting.name | |||
| json.nav_logo_url default_setting.nav_logo_url&.[](1..-1) | |||
| json.login_logo_url default_setting.login_logo_url&.[](1..-1) | |||
| @@ -35,11 +6,11 @@ json.setting do | |||
| json.site_page_deploy_domain @deploy_domain | |||
| json.subject_banner_url default_setting.subject_banner_url&.[](1..-1) | |||
| json.course_banner_url default_setting.course_banner_url&.[](1..-1) | |||
| # json.course_banner_url default_setting.course_banner_url&.[](1..-1) | |||
| json.competition_banner_url EduSetting.get("competition_banner_url").to_s | |||
| json.competition_banner_href EduSetting.get("competition_banner_href").to_s | |||
| json.moop_cases_banner_url default_setting.moop_cases_banner_url&.[](1..-1) | |||
| json.oj_banner_url default_setting.oj_banner_url&.[](1..-1) | |||
| # json.moop_cases_banner_url default_setting.moop_cases_banner_url&.[](1..-1) | |||
| # json.oj_banner_url default_setting.oj_banner_url&.[](1..-1) | |||
| json.navbar @navbar | |||
| @@ -62,15 +33,15 @@ json.setting do | |||
| end | |||
| json.common @common | |||
| json.third_party @third_party | |||
| # json.third_party @third_party | |||
| json.third_party_new @third_party_new | |||
| if @top_system_notification.present? | |||
| json.system_notification do | |||
| json.(@top_system_notification, :id, :subject, :sub_subject, :content) | |||
| json.is_read @top_system_notification.read_member?(current_user&.id) | |||
| end | |||
| else | |||
| json.system_notification nil | |||
| end | |||
| # if @top_system_notification.present? | |||
| # json.system_notification do | |||
| # json.(@top_system_notification, :id, :subject, :sub_subject, :content) | |||
| # json.is_read @top_system_notification.read_member?(current_user&.id) | |||
| # end | |||
| # else | |||
| # json.system_notification nil | |||
| # end | |||
| end | |||
| @@ -4,12 +4,12 @@ | |||
| # the maximum value specified for Puma. Default is set to 5 threads for minimum | |||
| # and maximum; this matches the default thread size of Active Record. | |||
| # | |||
| threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 } | |||
| threads_count = ENV.fetch("RAILS_MAX_THREADS") { 8 } | |||
| threads threads_count, threads_count | |||
| # Specifies the `port` that Puma will listen on to receive requests; default is 3000. | |||
| # | |||
| port ENV.fetch("PORT") { 3000 } | |||
| port ENV.fetch("PORT") { 4000 } | |||
| # Specifies the `environment` that Puma will run in. | |||
| # | |||
| @@ -21,7 +21,8 @@ environment ENV.fetch("RAILS_ENV") { "development" } | |||
| # Workers do not work on JRuby or Windows (both of which do not support | |||
| # processes). | |||
| # | |||
| # workers ENV.fetch("WEB_CONCURRENCY") { 2 } | |||
| workers ENV.fetch("WEB_CONCURRENCY") { 8 } | |||
| # Use the `preload_app!` method when specifying a `workers` number. | |||
| # This directive tells Puma to first boot the application and load code | |||
| @@ -0,0 +1,47 @@ | |||
| # Puma can serve each request in a thread from an internal thread pool. | |||
| # The `threads` method setting takes two numbers: a minimum and maximum. | |||
| # Any libraries that use thread pools should be configured to match | |||
| # the maximum value specified for Puma. Default is set to 5 threads for minimum | |||
| # and maximum; this matches the default thread size of Active Record. | |||
| # | |||
| threads_count = ENV.fetch("RAILS_MAX_THREADS") { 8 } | |||
| threads threads_count, threads_count * 2 | |||
| # Specifies the `port` that Puma will listen on to receive requests; default is 3000. | |||
| # | |||
| port ENV.fetch("PORT") { 4000 } | |||
| # Specifies the `environment` that Puma will run in. | |||
| # | |||
| environment ENV.fetch("RAILS_ENV") { "development" } | |||
| # Specifies the number of `workers` to boot in clustered mode. | |||
| # Workers are forked webserver processes. If using threads and workers together | |||
| # the concurrency of the application would be max `threads` * `workers`. | |||
| # Workers do not work on JRuby or Windows (both of which do not support | |||
| # processes). | |||
| # | |||
| # workers ENV.fetch("WEB_CONCURRENCY") { 8 } | |||
| # Use the `preload_app!` method when specifying a `workers` number. | |||
| # This directive tells Puma to first boot the application and load code | |||
| # before forking the application. This takes advantage of Copy On Write | |||
| # process behavior so workers use less memory. | |||
| # | |||
| # preload_app! | |||
| before_fork do | |||
| require 'puma_worker_killer' | |||
| PumaWorkerKiller.config do |config| | |||
| config.ram = 2048 # mb | |||
| config.frequency = 20 # seconds | |||
| config.percent_usage = 0.98 | |||
| #config.rolling_restart_frequency = 12 * 3600 # 12 hours in seconds, or 12.hours if using Rails | |||
| end | |||
| PumaWorkerKiller.start | |||
| end | |||
| # Allow puma to be restarted by `rails restart` command. | |||
| plugin :tmp_restart | |||
| @@ -1,6 +1,14 @@ | |||
| defaults format: :json do | |||
| namespace :api do | |||
| namespace :pm do | |||
| resources :weekly_issues, only: [:index] do | |||
| collection do | |||
| get :personal | |||
| get :group | |||
| get :group_issues | |||
| get :personal_issues | |||
| end | |||
| end | |||
| resources :dashboards,only: [:index] do | |||
| collection do | |||
| get :todo | |||
| @@ -51,6 +59,7 @@ defaults format: :json do | |||
| end | |||
| end | |||
| resources :action_runs, only: [:index] | |||
| resources :pipelines, only: [:index] | |||
| end | |||
| namespace :v1 do | |||
| @@ -109,6 +118,8 @@ defaults format: :json do | |||
| post :sonar_initialize | |||
| post :insert_file | |||
| get :doxygen_url | |||
| get :analyze_doxygen | |||
| end | |||
| end | |||
| @@ -148,7 +159,15 @@ defaults format: :json do | |||
| get :keyid | |||
| end | |||
| end | |||
| resources :portrait, only: [:index] | |||
| resources :portrait, only: [:index] do | |||
| collection do | |||
| get :community_impact | |||
| get :project_maturity | |||
| get :project_health | |||
| get :team_impact | |||
| get :develop_activity | |||
| end | |||
| end | |||
| resources :sync_repositories, only: [:create, :index] do | |||
| collection do | |||
| post :update_info | |||
| @@ -0,0 +1,5 @@ | |||
| class AddActionNodeInputDefaultValue < ActiveRecord::Migration[5.2] | |||
| def change | |||
| add_column :action_node_inputs, :default_value, :string | |||
| end | |||
| end | |||
| @@ -0,0 +1,5 @@ | |||
| class AddPipelinesType < ActiveRecord::Migration[5.2] | |||
| def change | |||
| add_column :action_pipelines, :pipeline_type, :integer, :default => 1 | |||
| end | |||
| end | |||
| @@ -0,0 +1,5 @@ | |||
| class AddUserIndexPhone < ActiveRecord::Migration[5.2] | |||
| def change | |||
| add_index :users, :phone | |||
| end | |||
| end | |||
| @@ -0,0 +1,5 @@ | |||
| class AddJournalDetailMsg < ActiveRecord::Migration[5.2] | |||
| def change | |||
| add_column :journal_details, :status_msg, :string | |||
| end | |||
| end | |||
| @@ -0,0 +1,7 @@ | |||
| class AddIssueEnterprise < ActiveRecord::Migration[5.2] | |||
| def change | |||
| add_column :issues, :enterprise_identifier, :string | |||
| add_index :issues, :enterprise_identifier | |||
| end | |||
| end | |||