diff --git a/app/controllers/api/pm/pipelines_controller.rb b/app/controllers/api/pm/pipelines_controller.rb index 933417ff2..1ad0fe085 100644 --- a/app/controllers/api/pm/pipelines_controller.rb +++ b/app/controllers/api/pm/pipelines_controller.rb @@ -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) diff --git a/app/controllers/api/v1/projects/pulls/pulls_controller.rb b/app/controllers/api/v1/projects/pulls/pulls_controller.rb index c8a1d0cab..65b7d78f7 100644 --- a/app/controllers/api/v1/projects/pulls/pulls_controller.rb +++ b/app/controllers/api/v1/projects/pulls/pulls_controller.rb @@ -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("合并请求重新打开失败!") diff --git a/app/controllers/competition_infos_controller.rb b/app/controllers/competition_infos_controller.rb index b3075b814..65606f1ef 100644 --- a/app/controllers/competition_infos_controller.rb +++ b/app/controllers/competition_infos_controller.rb @@ -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") diff --git a/app/controllers/journals_controller.rb b/app/controllers/journals_controller.rb index 5576d85af..6a8e572d3 100644 --- a/app/controllers/journals_controller.rb +++ b/app/controllers/journals_controller.rb @@ -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 diff --git a/app/controllers/pull_requests_controller.rb b/app/controllers/pull_requests_controller.rb index d3f042e3b..69f6c365a 100644 --- a/app/controllers/pull_requests_controller.rb +++ b/app/controllers/pull_requests_controller.rb @@ -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 diff --git a/app/controllers/version_releases_controller.rb b/app/controllers/version_releases_controller.rb index dd80bf6ab..29be84266 100644 --- a/app/controllers/version_releases_controller.rb +++ b/app/controllers/version_releases_controller.rb @@ -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, "发布失败") diff --git a/app/controllers/watchers_controller.rb b/app/controllers/watchers_controller.rb index 3e49c6e4c..fb4b29eb1 100644 --- a/app/controllers/watchers_controller.rb +++ b/app/controllers/watchers_controller.rb @@ -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) diff --git a/app/helpers/repositories_helper.rb b/app/helpers/repositories_helper.rb index 8a8d43688..66192abeb 100644 --- a/app/helpers/repositories_helper.rb +++ b/app/helpers/repositories_helper.rb @@ -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 diff --git a/app/models/competition_user.rb b/app/models/competition_user.rb index def0c9402..ed47369af 100644 --- a/app/models/competition_user.rb +++ b/app/models/competition_user.rb @@ -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 = [] diff --git a/app/models/issue.rb b/app/models/issue.rb index 4a960e78a..aa5481411 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -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 diff --git a/app/models/project_action.rb b/app/models/project_action.rb new file mode 100644 index 000000000..df212b521 --- /dev/null +++ b/app/models/project_action.rb @@ -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 diff --git a/app/models/project_actions/fork_event.rb b/app/models/project_actions/fork_event.rb new file mode 100644 index 000000000..0d9bb99b0 --- /dev/null +++ b/app/models/project_actions/fork_event.rb @@ -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 diff --git a/app/models/project_actions/issue_comment_event.rb b/app/models/project_actions/issue_comment_event.rb new file mode 100644 index 000000000..2a5a73fdd --- /dev/null +++ b/app/models/project_actions/issue_comment_event.rb @@ -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 diff --git a/app/models/project_actions/issues_event.rb b/app/models/project_actions/issues_event.rb new file mode 100644 index 000000000..a51536a35 --- /dev/null +++ b/app/models/project_actions/issues_event.rb @@ -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 diff --git a/app/models/project_actions/pull_request_event.rb b/app/models/project_actions/pull_request_event.rb new file mode 100644 index 000000000..b27e43c41 --- /dev/null +++ b/app/models/project_actions/pull_request_event.rb @@ -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 diff --git a/app/models/project_actions/pull_request_review_comment_event.rb b/app/models/project_actions/pull_request_review_comment_event.rb new file mode 100644 index 000000000..a1a2fa0f6 --- /dev/null +++ b/app/models/project_actions/pull_request_review_comment_event.rb @@ -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 diff --git a/app/models/project_actions/release_event.rb b/app/models/project_actions/release_event.rb new file mode 100644 index 000000000..2505d1603 --- /dev/null +++ b/app/models/project_actions/release_event.rb @@ -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 diff --git a/app/models/project_actions/star_event.rb b/app/models/project_actions/star_event.rb new file mode 100644 index 000000000..87e33650f --- /dev/null +++ b/app/models/project_actions/star_event.rb @@ -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 diff --git a/app/services/api/v1/issues/create_service.rb b/app/services/api/v1/issues/create_service.rb index fdbdc71ed..b0056aced 100644 --- a/app/services/api/v1/issues/create_service.rb +++ b/app/services/api/v1/issues/create_service.rb @@ -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? diff --git a/app/services/api/v1/issues/journals/create_service.rb b/app/services/api/v1/issues/journals/create_service.rb index 5f57c4f07..c04011610 100644 --- a/app/services/api/v1/issues/journals/create_service.rb +++ b/app/services/api/v1/issues/journals/create_service.rb @@ -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', {}) diff --git a/app/services/api/v1/issues/update_service.rb b/app/services/api/v1/issues/update_service.rb index dbdebf932..a28ff8324 100644 --- a/app/services/api/v1/issues/update_service.rb +++ b/app/services/api/v1/issues/update_service.rb @@ -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 # 更改标题 diff --git a/app/services/projects/fork_service.rb b/app/services/projects/fork_service.rb index 63475f2b4..0ec3bfabf 100644 --- a/app/services/projects/fork_service.rb +++ b/app/services/projects/fork_service.rb @@ -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 diff --git a/db/migrate/20250825061956_create_project_actions.rb b/db/migrate/20250825061956_create_project_actions.rb new file mode 100644 index 000000000..d2b72823d --- /dev/null +++ b/db/migrate/20250825061956_create_project_actions.rb @@ -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