Merge remote-tracking branch 'origin/dev_osredm_server' into dev_osredm_server

This commit is contained in:
xxq250 2025-09-08 10:12:35 +08:00
commit 2b4de4d11f
23 changed files with 297 additions and 9 deletions

View File

@ -23,7 +23,6 @@ class Api::Pm::PipelinesController < Api::Pm::BaseController
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)

View File

@ -24,6 +24,7 @@ class Api::V1::Projects::Pulls::PullsController < Api::V1::BaseController
else
@result_object = Api::V1::Projects::Pulls::ReopenService.call(@project, @pull_request, current_user)
if @result_object
ProjectActions::PullRequestEvent.build(@project, current_user, @pull_request, "reopened")
render_ok
else
render_error("合并请求重新打开失败!")

View File

@ -15,7 +15,7 @@ class CompetitionInfosController < ApplicationController
competition_infos = CompetitionInfo.order(sort_no: :desc)
competition_infos = competition_infos.where("competition_infos.title like ?", "%#{params[:name]}%") if params[:name].present?
competition_infos = competition_infos.joins(:watchers).where(watchers: { user_id: current_user.id }) if params[:category].to_s == "watched"
competition_infos = competition_infos.joins(:competition_users).where(competition_users: { user_id: current_user.id }) if params[:category].to_s == "joined"
competition_infos = competition_infos.joins(:competition_users).where(competition_users: { user_id: current_user.id }).or(competition_infos.joins(:competition_users).merge(CompetitionUser.with_member_phone(current_user.phone))) if params[:category].to_s == "joined"
competition_infos = competition_infos.where(status: ActiveModel::Type::Boolean.new.cast(params[:status])) if ActiveModel::Type::Boolean.new.cast(params[:status]).present?
if params[:is_expert_audit].present?
competition_infos = competition_infos.where(:is_expert_audit => params[:is_expert_audit].to_s == "true")

View File

@ -48,7 +48,7 @@ class JournalsController < ApplicationController
AtmeService.call(current_user, @atme_receivers, journal) if @atme_receivers.size > 0
TouchWebhookJob.set(wait: 5.seconds).perform_later('PullRequestComment', @issue&.id, current_user.id, journal.id, 'created', {})
# @issue.project_trends.create(user_id: current_user.id, project_id: @project.id, action_type: "journal")
ProjectActions::PullRequestReviewCommentEvent.build(@issue.project, current_user, @issue.pull_request, journal) if @issue.issue_classify == "pull_request"
# author: zxh
# 调用上链API
push_activity_2_blockchain("issue_comment_create", journal) if Site.has_blockchain? && @project.use_blockchain

View File

@ -75,7 +75,7 @@ class PullRequestsController < ApplicationController
SendTemplateMessageJob.perform_later('ProjectPullRequest', current_user.id, @pull_request&.id) if Site.has_notice_menu?
Rails.logger.info "[ATME] maybe to at such users: #{@atme_receivers.pluck(:login)}"
AtmeService.call(current_user, @atme_receivers, @pull_request) if @atme_receivers.size > 0
ProjectActions::PullRequestEvent.build(@project, current_user, @pull_request, "opened")
# author: zxh
# 调用上链API
push_activity_2_blockchain("pull_request_create", @pull_request) if Site.has_blockchain? && @project.use_blockchain
@ -179,6 +179,7 @@ class PullRequestsController < ApplicationController
# 合并请求下issue处理为关闭
@issue&.update_attributes!({status_id:5})
SendTemplateMessageJob.perform_later('PullRequestClosed', current_user.id, @pull_request.id) if Site.has_notice_menu?
ProjectActions::PullRequestEvent.build(@project, current_user, @pull_request, "closed")
normal_status(1, "已拒绝")
else
normal_status(-1, '合并失败')
@ -249,6 +250,7 @@ class PullRequestsController < ApplicationController
# 合并请求下issue处理为关闭
@issue&.update_attributes!({status_id:5})
ProjectActions::PullRequestEvent.build(@project, current_user, @pull_request, "closed")
SendTemplateMessageJob.perform_later('PullRequestMerged', current_user.id, @pull_request.id) if Site.has_notice_menu?
normal_status(1, "合并成功")
else

View File

@ -56,6 +56,7 @@ class VersionReleasesController < ApplicationController
if params[:attachment_ids].present?
create_attachments(params[:attachment_ids], version_release)
end
ProjectActions::ReleaseEvent.build(@project, current_user, version_release)
normal_status(0, "发布成功")
else
normal_status(-1, "发布失败")

View File

@ -30,6 +30,10 @@ class WatchersController < ApplicationController
watcher = current_user.watch!(@target)
watcher.ext_info = params[:ext_info]
watcher.save
if @target.is_a?(Project)
ProjectActions::StarEvent.build(@target, current_user)
end
current_user.watch!(@target)
render_ok({watchers_count: @target.watchers_count, watched: true})
rescue Exception => e
uid_logger_error(e.message)

View File

@ -157,10 +157,12 @@ module RepositoriesHelper
next if s_content.starts_with?('http://') || s_content.starts_with?('https://') || s_content.starts_with?('mailto:') || s_content.blank?
ext = File.extname(s_content)[1..-1]
ext = ext.split("?")[0] if ext.include?("?")
ext = ext.gsub(/ \".*\"/, "") if ext.include?(" ")
if (image_type?(ext) || download_type(ext)) && !ext.blank?
s_content = s_content.starts_with?("/") ? s_content[1..-1] : s_content[0..-1]
s_content = File.expand_path(s_content, file_path)
s_content = s_content.split("#{Rails.root}/")[1]
s_content = s_content.gsub(/ \".*\"/, "") if s_content.include?(" ")
next if s_content.blank?
# content = content.gsub(s[0], "/#{s_content}")
join_xxx = s_content.include?("?") ? "&" : "?"
@ -185,7 +187,15 @@ module RepositoriesHelper
when 'ss_href_1'
content = content.gsub("href=\'#{s[0]}\'", "href=\'#{s_content}\'")
else
content = content.gsub("(#{s[0]})", "(#{s_content})")
## md中图片处理包含中文名称tip
if s[0].to_s.include?(" ")
s1 = s[0].to_s.split(" ")
str1 = s1[0]
str2 = s1[1] if s1.size >1
content = content.gsub("(#{str1} #{str2})", "(#{s_content} #{str2})")
else
content = content.gsub("(#{s[0]})", "(#{s_content})")
end
end
else
path = [owner&.login, repo&.identifier, 'tree', ref, file_path].join("/")
@ -203,7 +213,7 @@ module RepositoriesHelper
content = content.gsub("href=\"#{s[0]}\"", "href=\"#{s_content}\"")
when 'ss_href_1'
content = content.gsub("href=\'#{s[0]}\'", "href=\'#{s_content}\'")
else
else
content = content.gsub("(#{s[0]})", "(#{s_content})")
end
end

View File

@ -62,6 +62,11 @@ class CompetitionUser < ApplicationRecord
# end
# end
#
scope :with_member_phone, -> (phone) {
where("members LIKE ?", "%\"phone\":\"#{phone}\"%")
}
def members_to_string
return [] if members.blank?
str = []

View File

@ -107,6 +107,7 @@ class Issue < ApplicationRecord
scope :closed, ->{where(status_id: 5)}
scope :opened, ->{where.not(status_id: 5)}
scope :with_assigner_info, -> {
select("DISTINCT issues.*, u.id AS user_id, CONVERT(COALESCE(u.nickname, u.login) USING gbk) AS user_name").
joins("LEFT JOIN (
SELECT ia.issue_id, ia.assigner_id
FROM issue_assigners ia
@ -121,7 +122,7 @@ class Issue < ApplicationRecord
scope :ordered_by_assigner, -> (sort_direction) {
order("CASE WHEN u.id IS NULL THEN 1 ELSE 0 END ASC")
.order("COALESCE(u.nickname, u.login) #{sort_direction}")
.order("CONVERT(COALESCE(u.nickname, u.login) USING gbk) #{sort_direction}")
}
after_create :incre_project_common, :incre_user_statistic, :incre_platform_statistic
before_save :check_pm_and_update_due_date

View File

@ -0,0 +1,24 @@
# == Schema Information
#
# Table name: project_actions
#
# id :integer not null, primary key
# project_id :integer
# type :string(255)
# user_id :integer
# event_extra :text(65535)
# created_at :datetime not null
# updated_at :datetime not null
#
# Indexes
#
# index_project_actions_on_project_id (project_id)
#
class ProjectAction < ApplicationRecord
belongs_to :project
belongs_to :user, optional: true
serialize :event_extra, Hash
end

View File

@ -0,0 +1,30 @@
# == Schema Information
#
# Table name: project_actions
#
# id :integer not null, primary key
# project_id :integer
# type :string(255)
# user_id :integer
# event_extra :text(65535)
# created_at :datetime not null
# updated_at :datetime not null
#
# Indexes
#
# index_project_actions_on_project_id (project_id)
#
class ProjectActions::ForkEvent < ProjectAction
def self.build(project, user, fork_project)
project_action = new(project: project, user: user)
project_action.event_extra = {
forkee_id: fork_project.id,
forkee_name: fork_project.identifier,
forkee_owner_id: fork_project.owner.id,
forkee_owner_login: fork_project.owner.login
}
project_action.save!
end
end

View File

@ -0,0 +1,29 @@
# == Schema Information
#
# Table name: project_actions
#
# id :integer not null, primary key
# project_id :integer
# type :string(255)
# user_id :integer
# event_extra :text(65535)
# created_at :datetime not null
# updated_at :datetime not null
#
# Indexes
#
# index_project_actions_on_project_id (project_id)
#
class ProjectActions::IssueCommentEvent < ProjectAction
def self.build(project, user, issue, journal)
project_action = new(project: project, user: user)
project_action.event_extra = {
issue_id: issue.id,
issue_number: issue.project_issues_index,
body: journal.notes
}
project_action.save!
end
end

View File

@ -0,0 +1,33 @@
# == Schema Information
#
# Table name: project_actions
#
# id :integer not null, primary key
# project_id :integer
# type :string(255)
# user_id :integer
# event_extra :text(65535)
# created_at :datetime not null
# updated_at :datetime not null
#
# Indexes
#
# index_project_actions_on_project_id (project_id)
#
class ProjectActions::IssuesEvent < ProjectAction
def self.build(project, user, issue, action)
project_action = new(project: project, user: user)
project_action.event_extra = {
issue_id: issue.id,
issue_number: issue.project_issues_index,
issue_author_id: issue.author_id,
issue_author_login: issue.user.login,
title: issue.subject,
body: issue.description,
action: action
}
project_action.save!
end
end

View File

@ -0,0 +1,41 @@
# == Schema Information
#
# Table name: project_actions
#
# id :integer not null, primary key
# project_id :integer
# type :string(255)
# user_id :integer
# event_extra :text(65535)
# created_at :datetime not null
# updated_at :datetime not null
#
# Indexes
#
# index_project_actions_on_project_id (project_id)
#
class ProjectActions::PullRequestEvent < ProjectAction
def self.build(project, user, pull_request, action)
project_action = new(project: project, user: user)
gitea_pull_request = Gitea::PullRequest::FilesService.call(project.owner.login, project.identifier, pull_request.gitea_number, project&.owner&.gitea_token)
project_action.event_extra = {
action: action,
pull_id: pull_request.id,
pull_number: pull_request.gitea_number,
title: pull_request.title,
body: pull_request.body,
git_diff: gitea_pull_request,
additions: gitea_pull_request['TotalAddition'],
deletions: gitea_pull_request['TotalDeletion'],
changed_files: gitea_pull_request['NumFiles'],
merged: pull_request.status == 1,
base_ref: pull_request.base,
head_repo_id: pull_request.is_original ? pull_request.fork_project_id : pull_request.project_id,
head_repo_name: pull_request.project&.identifier,
head_ref: pull_request.head
}
project_action.save!
end
end

View File

@ -0,0 +1,29 @@
# == Schema Information
#
# Table name: project_actions
#
# id :integer not null, primary key
# project_id :integer
# type :string(255)
# user_id :integer
# event_extra :text(65535)
# created_at :datetime not null
# updated_at :datetime not null
#
# Indexes
#
# index_project_actions_on_project_id (project_id)
#
class ProjectActions::PullRequestReviewCommentEvent < ProjectAction
def self.build(project, user, pull_request, journal)
project_action = new(project: project, user: user)
project_action.event_extra = {
pull_id: pull_request.id,
pull_number: pull_request.gitea_number,
body: journal.notes
}
project_action.save!
end
end

View File

@ -0,0 +1,29 @@
# == Schema Information
#
# Table name: project_actions
#
# id :integer not null, primary key
# project_id :integer
# type :string(255)
# user_id :integer
# event_extra :text(65535)
# created_at :datetime not null
# updated_at :datetime not null
#
# Indexes
#
# index_project_actions_on_project_id (project_id)
#
class ProjectActions::ReleaseEvent < ProjectAction
def self.build(project, user, version_release)
project_action = new(project: project, user: user)
project_action.event_extra = {
tag_name: version_release.tag_name,
name: version_release.name,
body: version_release.body
}
project_action.save!
end
end

View File

@ -0,0 +1,24 @@
# == Schema Information
#
# Table name: project_actions
#
# id :integer not null, primary key
# project_id :integer
# type :string(255)
# user_id :integer
# event_extra :text(65535)
# created_at :datetime not null
# updated_at :datetime not null
#
# Indexes
#
# index_project_actions_on_project_id (project_id)
#
class ProjectActions::StarEvent < ProjectAction
def self.build(project, user)
project_action = new(project: project, user: user)
project_action.save!
end
end

View File

@ -97,6 +97,9 @@ class Api::V1::Issues::CreateService < ApplicationService
# @信息发送
AtmeService.call(current_user, @atme_receivers, @created_issue) unless receivers_login.blank?
# 项目行为构建
ProjectActions::IssuesEvent.build(@project, current_user, @created_issue, 'opened')
# 发消息
if Site.has_notice_menu?
SendTemplateMessageJob.perform_later('IssueAssigned', current_user.id, @created_issue&.id, assigner_ids) unless assigner_ids.blank?

View File

@ -40,7 +40,7 @@ class Api::V1::Issues::Journals::CreateService < ApplicationService
@issue.save!
push_activity_2_blockchain("issue_comment_create", @created_journal) if Site.has_blockchain? && @issue.project&.use_blockchain
ProjectActions::IssueCommentEvent.build(@issue.project, current_user, @issue, @created_journal)
# @信息发送
AtmeService.call(current_user, @atme_receivers, @created_journal) unless receivers_login.blank?
TouchWebhookJob.set(wait: 5.seconds).perform_later('IssueComment', @issue&.id, @current_user.id, @created_journal.id, 'created', {})

View File

@ -98,6 +98,7 @@ class Api::V1::Issues::UpdateService < ApplicationService
build_after_issue_journal_details if @updated_issue.previous_changes.present? # 操作记录
build_previous_issue_changes
build_issue_project_trends if status_id.present? # 开关时间记录
build_project_actions
build_cirle_blockchain_token if blockchain_token_num.present?
unless @project.id.zero?
# @信息发送
@ -185,6 +186,15 @@ class Api::V1::Issues::UpdateService < ApplicationService
end
end
def build_project_actions
if @updated_issue.previous_changes["status_id"].present? && @updated_issue.previous_changes["status_id"][1] == 5
ProjectActions::IssuesEvent.build(@project, current_user, @updated_issue, 'closed')
end
if @updated_issue.previous_changes["status_id"].present? && @updated_issue.previous_changes["status_id"][0] == 5
ProjectActions::IssuesEvent.build(@project, current_user, @updated_issue, 'reopened')
end
end
def build_after_issue_journal_details
begin
# 更改标题

View File

@ -39,7 +39,8 @@ class Projects::ForkService < ApplicationService
ForkUser.create(project_id: @project.id, fork_project_id: clone_project.id, user_id: clone_project.user_id)
SendTemplateMessageJob.perform_later('ProjectForked', @target_owner.id, @project.id) if Site.has_notice_menu?
ProjectActions::ForkEvent.build(@project, @target_owner, clone_project)
clone_project
end
rescue => e

View File

@ -0,0 +1,12 @@
class CreateProjectActions < ActiveRecord::Migration[5.2]
def change
create_table :project_actions do |t|
t.references :project
t.string :type
t.integer :user_id
t.text :event_extra
t.timestamps
end
end
end