Merge pull request 'nps增加明细更新' (#330) from pre_trustie_server into trustie_server

This commit is contained in:
xxq250 2025-01-23 10:55:50 +08:00
commit 54c38fd9e7
37 changed files with 2566 additions and 389 deletions

View File

@ -6,7 +6,7 @@ class Action::NodeInputsController < ApplicationController
@node_inputs = @node.action_node_inputs
respond_to do |format|
format.html
format.json
format.json{ render_ok(data: @node_inputs.as_json) }
end
end

View File

@ -4,6 +4,10 @@ class Action::NodeTypesController < ApplicationController
def index
@node_types = Action::NodeType.all
respond_to do |format|
format.html
format.json { render_ok(data: @node_types.as_json) }
end
end
def create
@ -20,7 +24,10 @@ class Action::NodeTypesController < ApplicationController
end
def show
respond_to do |format|
format.html
format.json { render_ok(data: @node_type.as_json) }
end
end
def new
@ -45,7 +52,10 @@ class Action::NodeTypesController < ApplicationController
else
flash[:danger] = '删除失败'
end
redirect_to action_node_types_path
respond_to do |format|
format.html { redirect_to action_node_types_path }
format.json { render_ok }
end
end
private

View File

@ -1,18 +1,25 @@
class Action::NodesController < ApplicationController
before_action :require_admin, except: [:index]
# before_action :require_admin, except: [:index]
before_action :require_login
before_action :find_action_node, except: [:index, :create, :new]
def index
@node_types = Action::NodeType.all
no_node_type = Action::NodeType.find_by(name: "未分类")
@no_type_nodes = Action::Node.where(action_node_types_id: nil)
@no_type_nodes = Action::Node.where(action_node_types_id: nil).or(Action::Node.where(action_node_types_id: no_node_type.id)) if no_node_type.present?
respond_to do |format|
format.html { @nodes = Action::Node.all }
format.html { @nodes = Action::Node.where("name LIKE :search OR full_name LIKE :search", :search => "%#{params[:search]}%") }
format.json
end
end
def create
@node = Action::Node.new(node_params)
if params.require(:node).present? && params.require(:node)[:link_type_array].present?
@node.link_type = (params.require(:node)[:link_type_array] - [""]).join(",")
end
@node.user_id = current_user.id
respond_to do |format|
if @node.save
format.html { redirect_to action_nodes_path, notice: '创建成功.' }
@ -33,10 +40,16 @@ class Action::NodesController < ApplicationController
end
def edit
if @node.link_type.present?
@node.link_type_array = @node.link_type.to_s.split(",")
end
end
def update
if params.require(:node).present? && params.require(:node)[:link_type_array].present?
@node.link_type = (params.require(:node)[:link_type_array] - [""]).join(",")
end
@node.user_id = current_user.id if @node.user_id.blank?
@node.update(node_params)
respond_to do |format|
format.html { redirect_to action_nodes_path, notice: '更新成功.' }
@ -50,7 +63,10 @@ class Action::NodesController < ApplicationController
else
flash[:danger] = '删除失败'
end
redirect_to action_nodes_path
respond_to do |format|
format.html { redirect_to action_nodes_path }
format.json { render_ok() }
end
end
private
@ -61,9 +77,11 @@ class Action::NodesController < ApplicationController
def node_params
if params.require(:action_node)
params.require(:action_node).permit(:name, :label, :full_name, :description, :icon, :action_node_types_id, :is_local, :local_url, :yaml, :sort_no)
params.require(:action_node).permit(:name, :label, :full_name, :description, :icon, :action_node_types_id,
:is_local, :local_url, :yaml, :sort_no, :node_type, :is_mutil_link, :link_type, :link_type_array)
else
params.permit(:name, :label, :full_name, :description, :icon, :action_node_types_id, :is_local, :local_url, :yaml, :sort_no)
params.permit(:name, :label, :full_name, :description, :icon, :action_node_types_id, :is_local, :local_url,
:yaml, :sort_no, :node_type, :is_mutil_link, :link_type, :link_type_array)
end
end
end

View File

@ -49,7 +49,10 @@ class Action::TemplatesController < ApplicationController
else
flash[:danger] = '删除失败'
end
redirect_to action_templates_path
respond_to do |format|
format.html { redirect_to action_templates_path }
format.json { render_ok }
end
end
private

View File

@ -2,7 +2,7 @@ class Admins::NpsController < Admins::BaseController
before_action :require_business
def index
@on_off_switch = EduSetting.get("nps-on-off-switch").to_s == 'true'
@user_nps = UserNp.joins(:user).order(created_at: :desc)
@user_nps = UserNp.order(created_at: :desc)
keyword = params[:keyword].to_s.strip.presence
if keyword
sql = 'CONCAT(users.lastname, users.firstname) LIKE :keyword OR users.nickname LIKE :keyword OR users.login LIKE :keyword OR users.mail LIKE :keyword OR users.phone LIKE :keyword'

View File

@ -0,0 +1,137 @@
class Api::Pm::DashboardsController < Api::Pm::BaseController
before_action :require_login
def index
end
def todo
return render_error('请输入正确的pm_project_ids.') if params[:pm_project_ids].blank?
pm_project_ids = params[:pm_project_ids].split(",") rescue []
date = params[:date].present? ? params[:date].to_date : Date.today rescue Date.today
@issues = Issue.where("start_date <= ? and due_date >= ?", date, date)
@issues = @issues.where(pm_project_id: pm_project_ids).joins(:issue_participants).where(issue_participants: {participant_id: current_user.id, participant_type: 'assigned'})
@issues = @issues.where.not(status_id: 5)
@issues = kaminari_paginate(@issues.distinct.pm_includes)
end
def my_issues
return render_error('请输入正确的pm_project_ids.') if params[:pm_project_ids].blank?
return render_error('请输入正确的pm_issue_types.') if params[:pm_issue_types].blank?
pm_project_ids = params[:pm_project_ids].split(",") rescue []
pm_issue_types = params[:pm_issue_types].split(",") rescue []
@all_issues = Issue.where(pm_project_id: pm_project_ids, pm_issue_type: pm_issue_types)
@issues = @all_issues.joins(:issue_participants).where(issue_participants: {participant_id: current_user.id})
@issues = kaminari_paginate(@issues.distinct.pm_includes)
@my_assign_requirements_count = @all_issues.where(pm_issue_type: 1).joins(:issue_participants).where(issue_participants: {participant_id: current_user.id, participant_type: 'assigned'}).size
@my_assign_tasks_count = @all_issues.where(pm_issue_type: 2).joins(:issue_participants).where(issue_participants: {participant_id: current_user.id, participant_type: 'assigned'}).size
@my_assign_bugs_count = @all_issues.where(pm_issue_type: 3).joins(:issue_participants).where(issue_participants: {participant_id: current_user.id, participant_type: 'assigned'}).size
end
def my_pm_projects
return render_error('请输入正确的pm_project_id.') if params[:pm_project_id].blank?
@all_issues = Issue.where(pm_project_id: params[:pm_project_id])
time_now = Time.now
@last_week_create_issues_count = @all_issues.where("created_on > ? and created_on < ?", time_now - 7.days, time_now).size
@before_last_week_create_issue_count = @all_issues.where("created_on > ? and created_on < ?", time_now - 14.days, time_now - 7.days).size
@compare_last_week_create_issues = @before_last_week_create_issue_count.zero? ? 0 :(@last_week_create_issues_count - @before_last_week_create_issue_count).to_f / @before_last_week_create_issue_count rescue 0
@last_week_close_issues_count = @all_issues.where(status_id: 5).where("updated_on > ? and updated_on < ?", time_now - 7.days, time_now).size
@before_last_week_close_issue_count = @all_issues.where(status_id: 5).where("updated_on > ? and updated_on < ?", time_now - 14.days, time_now - 7.days).size
@compare_last_week_close_issues = @before_last_week_close_issue_count.zero? ? 0 :(@last_week_close_issues_count - @before_last_week_close_issue_count).to_f / @before_last_week_close_issue_count rescue 0
@all_requirement_issues_count = @all_issues.where(pm_issue_type: 1).size
@open_requirement_issues_count = @all_issues.where(pm_issue_type: 1).where.not(status_id: 5).size
@last_week_close_requirement_issues_count = @all_issues.where(pm_issue_type: 1).where(status_id: 5).where("updated_on > ? and updated_on < ?", time_now - 7.days, time_now).size
@last_month_close_requirement_issues_count = @all_issues.where(pm_issue_type: 1).where(status_id: 5).where("updated_on > ? and updated_on < ?", time_now - 30.days, time_now).size
@all_task_issues_count = @all_issues.where(pm_issue_type: 2).size
@open_task_issues_count = @all_issues.where(pm_issue_type: 2).where.not(status_id: 5).size
@last_week_close_tast_issues_count = @all_issues.where(pm_issue_type: 2).where(status_id: 5).where("updated_on > ? and updated_on < ?", time_now - 7.days, time_now).size
@last_month_close_task_issues_count = @all_issues.where(pm_issue_type: 2).where(status_id: 5).where("updated_on > ? and updated_on < ?", time_now - 30.days, time_now).size
@all_bug_issues_count = @all_issues.where(pm_issue_type: 3).size
@open_bug_issues_count = @all_issues.where(pm_issue_type: 3).where.not(status_id: 5).size
@last_week_close_bug_issues_count = @all_issues.where(pm_issue_type: 3).where(status_id: 5).where("updated_on > ? and updated_on < ?", time_now - 7.days, time_now).size
@last_month_close_bug_issues_count = @all_issues.where(pm_issue_type: 3).where(status_id: 5).where("updated_on > ? and updated_on < ?", time_now - 30.days, time_now).size
@requirement_close_trend = [[],[]]
@task_close_trend = [[],[]]
@bug_close_trend = [[],[]]
((time_now-29.days).to_date..time_now.to_date).to_a.each do |i|
@requirement_close_trend[0] << i.strftime("%Y.%m.%d")
@task_close_trend[0] << i.strftime("%Y.%m.%d")
@bug_close_trend[0] << i.strftime("%Y.%m.%d")
@requirement_close_trend[1] << @all_issues.where(pm_issue_type: 1, status_id: 5).where("DATE(updated_on) = ?", i).size
@task_close_trend[1] << @all_issues.where(pm_issue_type: 2, status_id: 5).where("DATE(updated_on) = ?", i).size
@bug_close_trend[1] << @all_issues.where(pm_issue_type: 3, status_id: 5).where("DATE(updated_on) = ?", i).size
end
@close_trend = {requirement: @requirement_close_trend, task: @task_close_trend, bug: @bug_close_trend}
render_ok(data: {
last_week_close_issues_count: @last_week_close_issues_count,
before_last_week_close_issue_count: @before_last_week_close_issue_count,
compare_last_week_close_issues: @compare_last_week_close_issues,
last_week_create_issues_count: @last_week_create_issues_count,
before_last_week_create_issue_count: @before_last_week_create_issue_count,
compare_last_week_create_issues: @compare_last_week_create_issues,
all_requirement_issues_count: @all_requirement_issues_count,
open_requirement_issues_count: @open_requirement_issues_count,
last_week_close_requirement_issues_count: @last_week_close_requirement_issues_count,
last_month_close_requirement_issues_count: @last_month_close_requirement_issues_count,
all_task_issues_count: @all_task_issues_count,
open_task_issues_count: @open_task_issues_count,
last_week_close_task_issues_count: @last_week_close_tast_issues_count,
last_month_close_task_issues_count: @last_month_close_task_issues_count,
all_bug_issues_count: @all_bug_issues_count,
open_bug_issues_count: @open_bug_issues_count,
last_week_close_bug_issues_count: @last_week_close_bug_issues_count,
last_month_close_bug_issues_count: @last_month_close_bug_issues_count,
close_trend: @close_trend
})
end
def my_projects
return render_error('请输入正确的project_id.') if params[:project_id].blank?
@project = Project.find_by_id params[:project_id]
return render_error('请输入正确的project_id.') unless @project.present?
time_now = Time.now
branch_tag_result = $gitea_hat_client.get_repos_branch_tag_count_by_owner_repo(@project&.owner&.login, @project&.identifier) rescue {}
languages_result = $gitea_client.get_repos_languages_by_owner_repo(@project&.owner&.login, @project&.identifier) rescue {}
@open_pull_requests_count = @project.pull_requests.opening.size
@last_week_close_pull_requests_count = @project.pull_requests.where(status: 1).where("updated_at > ? and updated_at < ?", time_now - 7.days, time_now).size
@last_month_close_pull_requets_count = @project.pull_requests.where(status: 1).where("updated_at > ? and updated_at < ?", time_now - 30.days, time_now).size
@commits_count = @project.commit_logs.size
@last_week_commits_count = @project.commit_logs.where("created_at > ? and created_at < ?", time_now - 7.days, time_now).size
@last_month_commits_count = @project.commit_logs.where("created_at > ? and created_at < ?", time_now - 30.days, time_now).size
render_ok(data: {
branch_count: branch_tag_result["branch_count"].to_i,
tag_count: branch_tag_result["tag_count"].to_i,
license_name: @project.license&.name,
open_pull_requests_count: @open_pull_requests_count,
last_week_close_pull_requests_count: @last_week_close_pull_requests_count,
last_month_close_pull_requets_count: @last_month_close_pull_requets_count,
commits_count: @commits_count,
last_week_commits_count: @last_week_commits_count,
last_month_commits_count: @last_month_commits_count,
language: hash_transform_precentagable(languages_result),
})
end
def my_operate_journals
return render_error('请输入正确的pm_project_id.') if params[:pm_project_id].blank?
@journals = Journal.operate_journals.joins(:issue).where(issues: {pm_project_id: params[:pm_project_id], pm_issue_type: [1,2,3]})
@journals = kaminari_paginate(@journals.order(updated_on: :desc))
end
private
def hash_transform_precentagable(hash)
total_byte_size = hash.values.sum
hash.transform_values { |v|
ActionController::Base.helpers
.number_to_percentage((v * 100.0 / total_byte_size), precision: 1)
}.select{|k,v| v != "0.0%"}
end
end

View File

@ -237,7 +237,47 @@ class Api::Pm::IssuesController < Api::Pm::BaseController
end
end
def link_issues
children_issues = @issue.pm_issue_type == 1 ? @issue.child_count > 0 ? Issue.where(id: @issue.id) : Issue.none : Issue.where(root_id: @issue.id)
linkable_issues = Issue.where(id: PmLink.where(linkable_type: "Issue", linkable_id: @issue.id).pluck(:be_linkable_id))
belinkable_issues = Issue.where(id: PmLink.where(be_linkable_type: "Issue", be_linkable_id: @issue.id).pluck(:linkable_id))
full_link_issues_ids = children_issues.pluck(:id) | linkable_issues.pluck(:id) | belinkable_issues.pluck(:id)
compare_link_issues_ids = children_issues.pluck(:id) | linkable_issues.pluck(:id) | belinkable_issues.pluck(:id)
i = compare_link_issues_ids.count
while i > 0 do
children_issues = Issue.where(root_id: compare_link_issues_ids)
linkable_issues = Issue.where(id: PmLink.where(linkable_type: "Issue", linkable_id: compare_link_issues_ids).pluck(:be_linkable_id))
belinkable_issues = Issue.where(id: PmLink.where(be_linkable_type: "Issue", be_linkable_id: compare_link_issues_ids).pluck(:linkable_id))
compare_link_issues_ids = (children_issues.pluck(:id) | linkable_issues.pluck(:id) | belinkable_issues.pluck(:id)) - full_link_issues_ids
full_link_issues_ids = full_link_issues_ids | compare_link_issues_ids
i = compare_link_issues_ids.count
end
exclude_issues_ids = []
exclude_issues = Issue.where(id: full_link_issues_ids).where.not(root_id: nil)
exclude_issues.each do |i|
exclude_issues_ids << i.id if i.pm_issue_type == 1 && full_link_issues_ids.include?(i.root_id)
end
full_link_issues_ids = full_link_issues_ids - exclude_issues_ids
@requirement_issues = Issue.where(id:full_link_issues_ids, pm_issue_type:1, root_id: nil).pm_includes
@task_issues = Issue.where(id:full_link_issues_ids, pm_issue_type:2).pm_includes
@bug_issues = Issue.where(id:full_link_issues_ids, pm_issue_type:3).pm_includes
end
private
def circle_link_issues(issue_ids)
if issue_ids.present?
children_issues = Issue.joins(:parent_issue).where(issues: {id: issue_ids})
linkable_issues = Issue.where(id: PmLink.where(linkable_type: "Issue", linkable_id: issue_ids))
belinkable_issues = Issue.where(id: PmLink.where(be_linkable_type: "Issue", be_linkable_id: issue_ids))
return circle_link_issues(children_issues.pluck(:id))
else
return []
end
end
def check_issue_operate_permission
return if params[:project_id].to_i.zero?
render_forbidden('您没有操作权限!') unless @project.member?(current_user) || current_user.admin? || @issue.user == current_user

View File

@ -56,12 +56,15 @@ class Api::Pm::ProjectsController < Api::Pm::BaseController
def statistics
return tip_exception '参数错误' if params[:pm_project_id].blank?
@issues = Issue.where(pm_project_id: params[:pm_project_id], pm_issue_type:[1, 2, 3])
@last_week_close_issues = @issues.where(status_id: 5).where("updated_on > ? and updated_on < ?", Time.now - 7.days, Time.now)
last_week_close_type_count_data = @last_week_close_issues.group(:pm_issue_type).count
type_count_data = @issues.group(:pm_issue_type).count
type_status = @issues.group(:pm_issue_type,:status_id).count
type_status_data = {}
IssueStatus.all.map do |e|
# next if e.id == 5
[1,2,3].map{ |type|
next if type == 1 && [1, 6].include?(e.id)
type_status_data[type] = {} if type_status_data[type].nil?
if type_status[[type,e.id]].nil?
type_status_data[type][e.id] = 0
@ -71,9 +74,9 @@ class Api::Pm::ProjectsController < Api::Pm::BaseController
}
end
open_data = {
"1": type_status_data[1][1].to_i + type_status_data[1][2].to_i,
"2": type_status_data[2][1].to_i + type_status_data[2][2].to_i,
"3": type_status_data[3][1].to_i + type_status_data[3][2].to_i,
"1": type_status_data[1][1].to_i + type_status_data[1][2].to_i + type_status_data[1][3].to_i + type_status_data[1][6].to_i,
"2": type_status_data[2][1].to_i + type_status_data[2][2].to_i + type_status_data[2][3].to_i + type_status_data[2][6].to_i,
"3": type_status_data[3][1].to_i + type_status_data[3][2].to_i + type_status_data[3][3].to_i + type_status_data[3][6].to_i,
}
if type_count_data.keys.size < 3
nedd_add = [1,2,3] - type_count_data.keys
@ -81,17 +84,24 @@ class Api::Pm::ProjectsController < Api::Pm::BaseController
type_count_data[e] = 0
}
end
if last_week_close_type_count_data.keys.size < 3
nedd_add = [1,2,3] - last_week_close_type_count_data.keys
nedd_add.map{ |e|
last_week_close_type_count_data[e] = 0
}
end
data = {
pie_chart: type_count_data,
bar_chart: type_status_data,
open_data: open_data
open_data: open_data,
last_week_close_data: last_week_close_type_count_data,
}
render_ok(data: data)
end
def polyline
return tip_exception '参数错误' if params[:pm_project_id].blank?
time_line = (Time.current.beginning_of_day - 6.day) .. Time.current
time_line = (Time.current.beginning_of_day - 29.day) .. Time.current
@create_issues = Issue.where(pm_project_id: params[:pm_project_id],created_on: time_line)
@due_issues = Issue.where(pm_project_id: params[:pm_project_id],status_id:[3,5],due_date: time_line)
@create_issues_count = @create_issues.group(:pm_issue_type,"DATE(created_on)").count
@ -100,7 +110,7 @@ class Api::Pm::ProjectsController < Api::Pm::BaseController
create_issues: {},
due_issues: {}
}
7.times do |time|
30.times do |time|
current_time = Date.current - time.day
if @create_issues_count.present?
data[:create_issues][current_time] = {

View File

@ -1,5 +1,49 @@
class Api::V1::Projects::Actions::ActionsController < Api::V1::Projects::Actions::BaseController
def new_index
@files = $gitea_client.get_repos_contents_by_owner_repo_filepath(@project&.owner&.login, @project&.identifier, ".gitea/workflows")
puts @files
@action_runs = Gitea::ActionRun.where(repo_id: @project.gpid, status: [1,2])
group_data = @action_runs.group(:workflow_id, :status).count
@result = []
@files.map{|i|i['name']}.each do |file|
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] == 1
end
@result << {
name: file,
last_action_run: last_action_run_json,
history: {
total: total,
success: success,
failure: failure,
}
}
end
render :json => @result
end
def index
begin
gitea_result = $gitea_hat_client.get_repos_actions_by_owner_repo(@project&.owner&.login, @project&.identifier)

File diff suppressed because it is too large Load Diff

View File

@ -12,7 +12,7 @@ class Organizations::ProjectsController < Organizations::BaseController
keywords = params[:search].to_s.each_char.select { |c| c.bytes.first < 240 }.join('')
@projects = @projects.where(id: params[:pm_project_repository_ids].split(',')) if params[:pm_project_repository_ids].present?
@projects = @projects.where.not(id: params[:exclude_ids].to_s.split(",")) if params[:exclude_ids].present?
@projects = @projects.where("gpid is not null") if params[:actived].present?
@projects = @projects.where(project_type: ['mirror', 'common']).where("gpid is not null") if params[:actived].present?
@projects = @projects.ransack(name_or_identifier_cont: keywords).result if params[:search].present?
@projects = @projects.includes(:owner).order("projects.#{sort} #{sort_direction}")
@projects = paginate(@projects)

View File

@ -17,11 +17,15 @@
# created_at :datetime not null
# updated_at :datetime not null
# label :string(255)
# node_type :string(255)
# is_mutil_link :boolean
# link_type :string(255)
#
# Indexes
#
# index_action_nodes_on_action_node_types_id (action_node_types_id)
# index_action_nodes_on_user_id (user_id)
# by_name (name)
# index_action_nodes_on_action_types_id (action_node_types_id)
# index_action_nodes_on_user_id (user_id)
#
class Action::Node < ApplicationRecord
@ -34,7 +38,7 @@ class Action::Node < ApplicationRecord
belongs_to :user, optional: true
attr_accessor :cust_name, :run_values, :input_values
attr_accessor :cust_name, :run_values, :input_values, :parent_node_id, :sub_nodes, :link_type_array, :node_id
validates :name, presence: { message: "不能为空" }
validates :full_name, length: { maximum: 200, too_long: "不能超过200个字符" }
@ -42,6 +46,7 @@ class Action::Node < ApplicationRecord
validates :description, length: { maximum: 65535, too_long: "不能超过65535个字符"}
def content_yaml
"foo".to_yaml
<<~YAML

View File

@ -0,0 +1,25 @@
# == Schema Information
#
# Table name: action_pipeline_results
#
# id :integer not null, primary key
# project_id :integer
# run_id :integer
# step_id :string(255)
# job_name :string(255)
# job_show_type :string(255)
# job_result :text(65535)
# created_at :datetime not null
# updated_at :datetime not null
#
# Indexes
#
# index_action_pipeline_results_on_project_id (project_id)
# index_action_pipeline_results_on_run_id (run_id)
#
class Action::PipelineResult < ApplicationRecord
self.table_name = 'action_pipeline_results'
belongs_to :project
end

View File

@ -0,0 +1,9 @@
class Gitea::ActionRun < Gitea::Base
self.inheritance_column = nil # FIX The single-table inheritance mechanism failed
# establish_connection :gitea_db
self.table_name = "action_run"
# belongs_to :user, class_name: '::User', primary_key: :gitea_uid, foreign_key: :owner_id, optional: true
end

View File

@ -102,6 +102,7 @@ class Issue < ApplicationRecord
scope :issue_issue, ->{where(issue_classify: [nil, 'issue'])}
scope :issue_pull_request, ->{where(issue_classify: 'pull_request')}
scope :issue_index_includes, ->{includes(:tracker, :priority, :version, :issue_status, :journals,:issue_tags,user: :user_extension)}
scope :pm_includes, -> {includes(:project, :show_issue_tags, :issue_status, :priority, :version, :user, :show_assigners, :comment_journals, :operate_journals)}
scope :closed, ->{where(status_id: 5)}
scope :opened, ->{where.not(status_id: 5)}
after_create :incre_project_common, :incre_user_statistic, :incre_platform_statistic

View File

@ -52,6 +52,7 @@ class Journal < ApplicationRecord
scope :journal_includes, ->{includes(:user, :journal_details, :attachments)}
scope :parent_journals, ->{where(parent_id: nil)}
scope :children_journals, lambda{|journal_id| where(parent_id: journal_id)}
scope :operate_journals, ->{where(notes: nil)}
enum state: {opened: 0, resolved: 1, disabled: 2}
@ -103,6 +104,21 @@ class Journal < ApplicationRecord
end
end
def pm_dashboard_operate_content
content = self.pm_operate_content
if content.start_with?('创建了')
content += "<b>#{self.issue.subject}</b>"
else
prefix = '将'
prefix += "计划" if self.issue.pm_issue_type == 1
prefix += "任务" if self.issue.pm_issue_type == 2
prefix += "缺陷" if self.issue.pm_issue_type == 3
prefix += "<b>#{self.issue.subject}</b>"
content = prefix + content.sub('将', '的')
end
content
end
def pm_operate_content
content = "#{operate_by_content}"
detail = self.journal_details.take

View File

@ -692,7 +692,11 @@ class User < Owner
# Returns the user who matches the given autologin +key+ or nil
def self.try_to_autologin(key)
user = Token.find_active_user('autologin', key)
user.update(last_login_on: Time.now) if user
if user
Rails.cache.fetch("user::update::last_login_on::#{user.id}",:expires_in => 5.minutes) do
user.update(last_login_on: Time.now)
end
end
user
end

View File

@ -87,14 +87,22 @@ class Cache::V2::UserDateRankService < ApplicationService
def set_user_rank
set_user_statistic
follow_count = $redis_cache.hget(user_date_statistic_key, "follow-count") || 0
follow_count = follow_count.to_i < 0 ? 0 : follow_count
pullrequest_count = $redis_cache.hget(user_date_statistic_key, "pullrequest-count") || 0
pullrequest_count = pullrequest_count.to_i < 0 ? 0 : pullrequest_count
issues_count = $redis_cache.hget(user_date_statistic_key, "issue-count") || 0
issues_count = issues_count.to_i < 0 ? 0 : issues_count
project_count = $redis_cache.hget(user_date_statistic_key, "project-count") || 0
project_count = project_count.to_i < 0 ? 0 : project_count
fork_count = $redis_cache.hget(user_date_statistic_key, "fork-count") || 0
fork_count = fork_count.to_i < 0 ? 0 : fork_count
project_watchers_count = $redis_cache.hget(user_date_statistic_key, "project-watcher-count") || 0
project_watchers_count = project_watchers_count.to_i < 0 ? 0 : project_watchers_count
project_praises_count = $redis_cache.hget(user_date_statistic_key, "project-praise-count") || 0
project_praises_count = project_praises_count.to_i < 0 ? 0 : project_praises_count
project_language = $redis_cache.hget(user_date_statistic_key, "project-language")
project_languages_count = project_language.nil? || project_language == "{}" ? 0 : JSON.parse(project_language).length
project_languages_count = project_languages_count.to_i < 0 ? 0 : project_languages_count
# 影响力
influence = (60.0 + follow_count.to_i / (follow_count.to_i + 20.0) * 40.0).to_i

View File

@ -11,7 +11,7 @@
<!-- </div>-->
<%# end %>
<div class="form-group ">
<label for="status">类</label>
<label for="status">节点分类:</label>
<%= form.select :action_node_types_id, options_for_select(Action::NodeType.all.map { |key| [key.name, key.id]}, node.action_node_types_id), {}, class: "form-control" %>
</div>
<div class="field">
@ -26,6 +26,22 @@
<%= form.label :full_name, "节点全名" %>
<%= form.text_field :full_name %>
</div>
<div class="form-group ">
<label for="status">类型:</label>
<% node_type_options = [['action节点', 'step' ], ['启动', 'start' ], ['任务', 'job']] %>
<%= form.select :node_type, options_for_select(node_type_options, node.node_type), {}, class: "form-control" %>
</div>
<div class="form-group ">
<label for="status">是否支持分支:</label>
<% is_mutil_link_options = [['否', false ], ['是', true]] %>
<%= form.select :is_mutil_link, options_for_select(is_mutil_link_options, node.is_mutil_link), {}, class: "form-control" %>
</div>
<div class="form-group ">
<label for="status">可连接到类型:</label>
<% link_type_options = [Action::Node.new(name: "job", label: "任务"), Action::Node.new(name: "step", label: "action节点")] %>
<%= collection_check_boxes(:node, :link_type_array, link_type_options, :name, :label) %>
</div>
<div class="field">
<%= form.label :description, "描述" %>

View File

@ -5,6 +5,15 @@
<p><a href="<%= action_templates_path %>" style="font-size: 14px;">>>前往模板配置</a></p>
<p>说明该界面适用于action 节点配置参数配置</p>
<div class="box search-form-container edu_settings-list-form">
<%= form_tag(action_nodes_path, method: :get, class: 'form-inline search-form flex-1') do %>
<%= text_field_tag(:search, params[:search], class: 'form-control col-12 col-md-2 mr-3', placeholder: '关键字检索') %>
<%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %>
<input type="reset" class="btn btn-secondary clear-btn" value="清空"/>
<% end %>
<%= link_to "新增", new_action_node_path, remote: true, class: "btn btn-primary pull-right", "data-disabled-with":"...新增" %>
</div>
<table border="1" width="100%">
<thead>
<tr>

View File

@ -2,7 +2,7 @@ json.types @node_types.each do |node_type|
if node_type.name.to_s == "未分类"
json.extract! node_type, :id, :name
json.nodes @no_type_nodes do |node|
json.extract! node, :id, :label, :name, :full_name, :description, :icon, :action_node_types_id, :yaml, :sort_no, :use_count
json.extract! node, :id, :label, :name, :full_name, :description, :icon, :action_node_types_id, :yaml, :sort_no, :use_count, :node_type, :is_mutil_link, :link_type
json.inputs node.action_node_inputs do |node_input|
json.partial! "node_input", locals: { node_input: node_input, node: node }
end
@ -10,7 +10,7 @@ json.types @node_types.each do |node_type|
else
json.extract! node_type, :id, :name
json.nodes node_type.action_nodes do |node|
json.extract! node, :id, :label, :name, :full_name, :description, :icon, :action_node_types_id, :yaml, :sort_no, :use_count
json.extract! node, :id, :label, :name, :full_name, :description, :icon, :action_node_types_id, :yaml, :sort_no, :use_count, :node_type, :is_mutil_link, :link_type
json.inputs node.action_node_inputs do |node_input|
json.partial! "node_input", locals: { node_input: node_input, node: node }
end

View File

@ -1,7 +1,7 @@
json.status 0
json.message "success"
json.extract! @node, :id, :name, :full_name, :description, :action_node_types_id, :is_local, :local_url, :yaml, :sort_no, :use_count
json.extract! @node, :id, :name, :full_name, :description, :icon, :action_node_types_id, :is_local, :local_url, :yaml, :sort_no, :use_count, :label, :node_type, :is_mutil_link, :link_type
json.inputs @node.action_node_inputs do |node_input|
json.partial! "node_input", locals: { node_input: node_input, node: @node }
end

View File

@ -12,15 +12,15 @@
<tbody>
<% if user_nps.present? %>
<% user_nps.each_with_index do |nps, index| %>
<tr class="user-item-<%= nps.user.id %>">
<tr class="user-item-<%= nps.user.nil? ? "用户已注销" : nps.user.id %>">
<td><%= list_index_no((params[:page] || 1).to_i, index) %></td>
<td class="text-left">
<%= link_to "/#{nps.user.login}", target: '_blank' do %>
<%= overflow_hidden_span nps.user.real_name, width: 100 %>
<%= link_to "/#{nps.user.nil? ? "用户已注销" : nps.user.login}", target: '_blank' do %>
<%= overflow_hidden_span (nps.user.nil? ? "用户已注销" : nps.user.real_name), width: 100 %>
<% end %>
</td>
<td><%= display_text(nps.created_at&.strftime('%Y-%m-%d %H:%M')) %></td>
<td><%= display_text(nps.user.last_login_on&.strftime('%Y-%m-%d %H:%M')) %></td>
<td><%= display_text(nps.user.nil? ? "用户已注销" : nps.user.last_login_on&.strftime('%Y-%m-%d %H:%M')) %></td>
<td><%= nps.action_type == 'close' ? '--' : nps.score %></td>
<td><%= nps.memo %></td>
</tr>

View File

@ -37,6 +37,21 @@
提升用户体验:<span class="text-danger"><%= UserNp.where("memo like '%用户体验需进一步提升%'").count %></span>
其他:<span class="text-danger"><%= UserNp.where("action_type !='close'").where("LENGTH(memo) >0").where.not(id: UserNp.where("memo like '%期待更加丰富的功能%' or memo like '%希望有新手引导%' or memo like '%用户体验需进一步提升%' ").ids).count %></span>
</p>
<p style="padding-bottom: 10px !important;">
代码库基本功能:<span class="text-danger"><%= UserNp.where("memo like '%代码库基本功能%'").count %></span>
疑修:<span class="text-danger"><%= UserNp.where("memo like '%疑修%'").count %></span>
合并请求:<span class="text-danger"><%= UserNp.where("memo like '%合并请求%'").count %></span>
流水线引擎:<span class="text-danger"><%= UserNp.where("memo like '%流水线引擎%'").count %></span>
维基Wiki<span class="text-danger"><%= UserNp.where("memo like '%维基Wiki%'").count %></span>
数据集:<span class="text-danger"><%= UserNp.where("memo like '%数据集%'").count %></span>
特色专区:<span class="text-danger"><%= UserNp.where("memo like '%特色专区%'").count %></span>
BOT功能<span class="text-danger"><%= UserNp.where("memo like '%BOT功能%'").count %></span>
跨平台同步服务:<span class="text-danger"><%= UserNp.where("memo like '%跨平台同步服务%'").count %></span>
代码溯源及扫描服务:<span class="text-danger"><%= UserNp.where("memo like '%代码溯源及扫描服务%'").count %></span>
开源软件健康度量服务:<span class="text-danger"><%= UserNp.where("memo like '%开源软件健康度量服务%'").count %></span>
HiAgent<span class="text-danger"><%= UserNp.where("memo like '%HiAgent%'").count %></span>
非常满意,没有需要吐槽的功能!:<span class="text-danger"><%= UserNp.where("memo like '%非常满意,没有需要吐槽的功能%'").count %></span>
</p>
</div>
<div class="box admin-list-container users-list-container">
<%= render partial: 'admins/nps/user_np_list', locals: { user_nps: @user_nps } %>

View File

@ -0,0 +1,11 @@
json.status 0
json.message "success"
json.data do
json.total_count @issues.total_count
json.my_assign_requirements_count @my_assign_requirements_count
json.my_assign_tasks_count @my_assign_tasks_count
json.my_assign_bugs_count @my_assign_bugs_count
json.issues @issues.each do |issue|
json.partial! "api/v1/issues/simple_detail", locals: {issue: issue}
end
end

View File

@ -0,0 +1,25 @@
json.status 0
json.message "success"
json.data do
json.total_count @journals.total_count
json.journals @journals do |journal|
journal.associate_attachment_container
json.id journal.id
json.is_journal_detail journal.is_journal_detail?
json.created_at journal.created_on.strftime("%Y-%m-%d %H:%M")
json.updated_at journal.updated_on.strftime("%Y-%m-%d %H:%M")
json.created_time journal.created_on.to_i
json.updated_time journal.updated_on.to_i
json.user do
if journal.user.present?
json.partial! "api/v1/users/simple_user", user: journal.user
else
json.nil!
end
end
detail = journal.journal_details.take
json.operate_category journal.pm_operate_category
json.operate_content journal.is_journal_detail? ? journal.pm_dashboard_operate_content : nil
end
end

View File

@ -0,0 +1,10 @@
json.status 0
json.message "success"
json.data do
json.total_count @issues.total_count
json.issues @issues.each do |issue|
json.partial! "api/v1/issues/simple_detail", locals: {issue: issue}
end
end

View File

@ -0,0 +1,11 @@
json.requirement_issues @requirement_issues.each do |issue|
json.partial! "api/v1/issues/simple_detail", locals: {issue: issue}
end
json.task_issues @task_issues.each do |issue|
json.partial! "api/v1/issues/simple_detail", locals: {issue: issue}
end
json.bug_issues @bug_issues.each do |issue|
json.partial! "api/v1/issues/simple_detail", locals: {issue: issue}
end

View File

@ -38,4 +38,6 @@ end
json.assigners issue.show_assigners.each do |assigner|
json.partial! "api/v1/users/simple_user", locals: {user: assigner}
end
json.comment_journals_count issue.comment_journals.size
json.comment_journals_count issue.comment_journals.size
json.start_date issue.start_date
json.due_date issue.due_date

View File

@ -0,0 +1,29 @@
jobs:
<%@job_nodes.each_with_index do |job,index| %>
job<%=index + 1 %>:
name: "<%=job.label || job.name %>"
# 运行环境,这里就是上面定义的多个 os
runs-on: 'ubuntu-latest'
<% if index >0 %>
needs: job<%=index %>
<% end %>
steps:
<%job.sub_nodes.each do |node| %>
- name: <%=node.label || node.name %>
<% if node.name !="shell" %>
uses: <%=node.full_name %>
<% end %>
<%if node.input_values.present? %>
with:
<% node.input_values.each_key do |key| %>
<%=key %>: '<%=node.input_values[key] %>'
<%end %>
<%end %>
<%if node.run_values.present? %>
<% node.run_values.each_key do |key| %>
<%=key %>: |
<%=node.run_values[key] %>
<%end %>
<%end %>
<% end %>
<%end %>

View File

@ -0,0 +1,51 @@
# steps:
# 将job的工作目录指向$GITHUB_WORSPACES checkout@v2比较旧不推荐使用
- name: Checkout codes
uses: actions/checkout@v3
- name: Install Java and Maven
uses: actions/setup-java@v3
with:
java-version: '11'
distribution: 'temurin'
# 设置jdk环境
- name: download latest temurin JDK
id: download_latest_jdk
env:
HTTPS_PROXY: http://172.20.32.253:3128
HTTP_PROXY: http://172.20.32.253:3128
#run: curl -o https://testgitea2.trustie.net/xxq250/licensee-identify-api-sss/raw/branch/master/openlogic-openjdk-11.0.22+7-linux-x64.tar.gz
run: wget -O $RUNNER_TEMP/java_package.tar.gz "http://172.20.32.202:10082/xxq250/licensee-identify-api-sss/raw/branch/master/OpenJDK11U-jdk_x64_linux_hotspot_11.0.22_7.tar.gz"
- uses: actions/setup-java@v4
with:
distribution: 'jdkfile'
jdkFile: ${{ runner.temp }}/java_package.tar.gz
java-version: '11.0.0'
architecture: x64
mvn-toolchain-vendor: 'Oracle'
# 设置maven 仓库缓存 避免每次构建时都重新下载依赖
- name: Cache local Maven repository
uses: actions/cache@v3
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
restore-keys: |
${{ runner.os }}-maven-
- name: Test java version
run: java -version
- name: Set up Maven
uses: stCarolas/setup-maven@v5
with:
maven-version: 3.8.2
- name: Setup Maven mirrors
uses: s4u/maven-settings-action@v3.0.0
with:
mirrors: '[{"id": "alimaven", "name": "aliyun maven", "mirrorOf": "central", "url": "http://172.20.32.181:30005/repository/aliyun-maven/"}]'
- name: env show
run: env
- name: cat maven-settings.xml
run: cat /root/.m2/settings.xml
- name: Test with Maven
run: mvn clean test -B -U
env:
https_proxy: http://172.20.32.253:3128
http_proxy: http://172.20.32.253:3128

View File

@ -1,15 +1,12 @@
# action name
name: <%=@pipeline_name %>
# 什么时候触发这个workflow
name: "<%=@pipeline_name %>"
on:
<%@on_nodes.each do |node| %>
<%if node.name.to_s.include?("on-push") %>
<%if node.name.to_s.include?("on-push") && node.input_values.present? %>
push:
<% node.input_values.each_key do |key| %>
<%=key %>:
<% if node.input_values[key].blank? %>
- *
- '*'
<% else %>
<% node.input_values[key].to_s.split(",").each do |val| %>
- <%=val %>
@ -17,20 +14,20 @@ on:
<% end %>
<% end %>
<% end %>
<%if node.name.to_s.include?("on-pull_request") %>
<%if node.name.to_s.include?("on-pull_request") && node.input_values.present? %>
pull_request:
<% node.input_values.each_key do |key| %>
<%=key %>:
<% if node.input_values[key].blank? %>
- *
- '*'
<% else %>
<% node.input_values[key].to_s.split(",").each do |val| %>
- <%=val %>
- <%=val %>
<% end %>
<% end %>
<% end %>
<% end %>
<%if node.name.to_s.include?("on-schedule") %>
<%if node.name.to_s.include?("on-schedule") && node.input_values.present? %>
schedule:
<% node.input_values.each_key do |key| %>
- <%=key %>: "<%=node.input_values[key] %>"
@ -39,16 +36,21 @@ on:
<% end %>
jobs:
job1:
# 运行环境
<%@job_nodes.each_with_index do |job,index| %>
<%=job.node_id %>:
name: "<%=job.label || job.name %>[<%=job.node_id %>]"
# 运行环境,这里就是上面定义的多个 os
runs-on: 'ubuntu-latest'
<% if index >0 %>
needs: <%=job.parent_node_id %>
<% end %>
steps:
<%@steps_nodes.each do |node| %>
- name: <%=node.label || node.name %>
<% if node.name !="shell" %>
<%job.sub_nodes.each do |node| %>
- name: "<%=node.label || node.name %>[<%=node.node_id %>]"
<% if node.name !="shell" %>
uses: <%=node.full_name %>
<% end %>
<%if node.input_values.present? %>
<% end %>
<%if node.input_values.present? %>
with:
<% node.input_values.each_key do |key| %>
<%=key %>: '<%=node.input_values[key] %>'
@ -56,7 +58,9 @@ jobs:
<%end %>
<%if node.run_values.present? %>
<% node.run_values.each_key do |key| %>
<%=key %>: '<%=node.run_values[key] %>'
<%=key %>: |
<%=node.run_values[key] %>
<%end %>
<%end %>
<% end %>
<%end %>

View File

@ -1,22 +1,20 @@
name: Check dist<%= @name %>
# action name
name: Test with Junit
# 什么时候触发这个workflow
on:
# push 到master分之的时候 这里可以指定多个
#push:
# branches:
# - master
# paths-ignore:
# - '**.md'
push:
branches:
- master
paths-ignore:
- '**.md'
# pull request 到master分之的时候, 这里可以指定多个
#pull_request:
# branches:
# - master
# paths-ignore:
# - '**.md'
pull_request:
branches:
- master
paths-ignore:
- '**.md'
# 定时调度执行
schedule:
- cron: '26 10,11 * * *'
@ -35,16 +33,15 @@ jobs:
os: [ 'ubuntu-latest' ]
# 运行环境,这里就是上面定义的多个 os
runs-on: 'ubuntu-latest'
steps:
# 将job的工作目录指向$GITHUB_WORSPACES checkout@v2比较旧不推荐使用
- name: Checkout codes
uses: actions/checkout@v3
#- name: Install Java and Maven
# uses: actions/setup-java@v3
# with:
# java-version: '11'
# distribution: 'temurin'
- name: Install Java and Maven
uses: actions/setup-java@v3
with:
java-version: '11'
distribution: 'temurin'
# 设置jdk环境
- name: download latest temurin JDK
id: download_latest_jdk

View File

@ -0,0 +1,26 @@
# action name
name: Test with Junit
# 什么时候触发这个workflow
on:
# push 到master分之的时候 这里可以指定多个
push:
branches:
- master
paths-ignore:
- '**.md'
# pull request 到master分之的时候, 这里可以指定多个
pull_request:
branches:
- master
paths-ignore:
- '**.md'
# 定时调度执行
schedule:
- cron: '26 10,11 * * *'
env:
https_proxy: http://172.20.32.253:3128
http_proxy: http://172.20.32.253:3128
# 一个workflow可以由多个job组成多个job可以并行运行
<%= render(partial: 'api/v1/projects/pipelines/jobs') %>

View File

@ -1,6 +1,15 @@
defaults format: :json do
namespace :api do
namespace :pm do
resources :dashboards,only: [:index] do
collection do
get :todo
get :my_issues
get :my_pm_projects
get :my_projects
get :my_operate_journals
end
end
resources :issues do
collection do
patch :batch_update
@ -14,6 +23,7 @@ defaults format: :json do
member do
get :link_index
get :parent_issues
get :link_issues
end
resources :issue_links
@ -152,6 +162,7 @@ defaults format: :json do
resource :dataset, only: [:create, :update, :show]
resources :actions, module: 'actions' do
collection do
get :new_index
post :disable
post :enable
resources :runs, only: [:index, :create] do
@ -165,6 +176,9 @@ defaults format: :json do
resources :pipelines do
post :build_yaml, on: :collection
post :save_yaml, on: :collection
post :upload_results, on: :collection
get :run_results, on: :collection
get :test_yaml, on: :collection
end
resources :pulls, module: 'pulls' do
member do

View File

@ -0,0 +1,7 @@
class AddActionNodesType < ActiveRecord::Migration[5.2]
def change
add_column :action_nodes, :node_type, :string
add_column :action_nodes, :is_mutil_link, :boolean
add_column :action_nodes, :link_type, :string
end
end

View File

@ -0,0 +1,15 @@
class CreateActionPipelineResults < ActiveRecord::Migration[5.2]
def change
create_table :action_pipeline_results do |t|
t.references :project
t.integer :run_id
t.string :step_id
t.string :job_name
t.string :job_show_type
t.text :job_result
t.timestamps
end
add_index :action_pipeline_results, :run_id
end
end