新增:疑修创建以及详情接口

This commit is contained in:
yystopf 2023-02-10 11:38:51 +08:00
parent 934b42f1a1
commit 53c2ffffb3
16 changed files with 236 additions and 7 deletions

View File

@ -1,12 +1,25 @@
class Api::V1::IssuesController < Api::V1::BaseController class Api::V1::IssuesController < Api::V1::BaseController
before_action :require_public_and_member_above, only: [:index] before_action :require_public_and_member_above, only: [:index, :show, :create, :update, :destroy]
def index def index
@object_results = Api::V1::Issues::ListService.call(@project, query_params, current_user) @object_results = Api::V1::Issues::ListService.call(@project, query_params, current_user)
@issues = kaminari_paginate(@object_results) @issues = kaminari_paginate(@object_results)
end end
def create
@object_result = Api::V1::Issues::CreateService.call(@project, issue_params, current_user)
end
before_action :load_issue, only: [:show, :update, :destroy]
def show
end
def update
@object_result = Api::V1::Issues::EditService.call(@project, issue_params, current_user)
end
private private
def query_params def query_params
@ -20,4 +33,23 @@ class Api::V1::IssuesController < Api::V1::BaseController
:issue_tag_ids => []) :issue_tag_ids => [])
end end
def issue_params
params.permit(
:status_id, :priority_id, :milestone_id,
:branch_name, :start_date, :due_date,
:subject, :description,
:issue_tag_ids => [],
:assigner_ids => [],
:attachment_ids => [])
end
def load_issue
@issue = @project.issues.where(project_issues_index: params[:id]).where.not(id: params[:id]).take || Issue.find_by_id(params[:id])
if @issue.blank?
render_not_found("疑修不存在!")
elsif @issue.present? && @issue.is_lock &&!(@project.member?(current_user) || current_user.admin?)
render_forbidden("您没有权限操作!")
end
end
end end

View File

@ -111,7 +111,9 @@ class IssuesController < ApplicationController
issue_params = issue_send_params(params) issue_params = issue_send_params(params)
Issues::CreateForm.new({subject: issue_params[:subject], description: issue_params[:description].blank? ? issue_params[:description] : issue_params[:description].b}).validate! Issues::CreateForm.new({subject: issue_params[:subject], description: issue_params[:description].blank? ? issue_params[:description] : issue_params[:description].b}).validate!
@issue = Issue.new(issue_params) @issue = Issue.new(issue_params)
@issue.project_issues_index = @project.get_last_project_issues_index + 1
if @issue.save! if @issue.save!
@project.del_project_issue_cache_delete_count
SendTemplateMessageJob.perform_later('IssueAssigned', current_user.id, @issue&.id) if Site.has_notice_menu? SendTemplateMessageJob.perform_later('IssueAssigned', current_user.id, @issue&.id) if Site.has_notice_menu?
SendTemplateMessageJob.perform_later('ProjectIssue', current_user.id, @issue&.id) if Site.has_notice_menu? SendTemplateMessageJob.perform_later('ProjectIssue', current_user.id, @issue&.id) if Site.has_notice_menu?
if params[:attachment_ids].present? if params[:attachment_ids].present?
@ -302,6 +304,7 @@ class IssuesController < ApplicationController
login = @issue.user.try(:login) login = @issue.user.try(:login)
SendTemplateMessageJob.perform_later('IssueDeleted', current_user.id, @issue&.subject, @issue.assigned_to_id, @issue.author_id) if Site.has_notice_menu? SendTemplateMessageJob.perform_later('IssueDeleted', current_user.id, @issue&.subject, @issue.assigned_to_id, @issue.author_id) if Site.has_notice_menu?
if @issue.destroy if @issue.destroy
@project.incre_project_issue_cache_delete_count
if issue_type == "2" && status_id != 5 if issue_type == "2" && status_id != 5
post_to_chain("add", token, login) post_to_chain("add", token, login)
end end

View File

@ -73,6 +73,7 @@ class Issue < ApplicationRecord
has_many :issue_participants has_many :issue_participants
has_many :participants, through: :issue_participants has_many :participants, through: :issue_participants
has_many :comment_journals, -> {where.not(notes: nil)}, class_name: "Journal", :as => :journalized has_many :comment_journals, -> {where.not(notes: nil)}, class_name: "Journal", :as => :journalized
has_many :operate_journals, -> {where(notes: nil)}, class_name: "Journal", :as => :journalized
scope :issue_includes, ->{includes(:user)} scope :issue_includes, ->{includes(:user)}
scope :issue_many_includes, ->{includes(journals: :user)} scope :issue_many_includes, ->{includes(journals: :user)}

View File

@ -424,4 +424,19 @@ class Project < ApplicationRecord
raise("项目名称包含敏感词汇,请重新输入") if name && !HarmoniousDictionary.clean?(name) raise("项目名称包含敏感词汇,请重新输入") if name && !HarmoniousDictionary.clean?(name)
raise("项目描述包含敏感词汇,请重新输入") if description && !HarmoniousDictionary.clean?(description) raise("项目描述包含敏感词汇,请重新输入") if description && !HarmoniousDictionary.clean?(description)
end end
def get_last_project_issues_index
last_issue = self.issues.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 : 1
end
def incre_project_issue_cache_delete_count
$redis_cache.hincrby("issue_cache_delete_count", self.id, 1)
end
def del_project_issue_cache_delete_count
$redis_cache.hdel("issue_cache_delete_count", self.id)
end
end end

View File

@ -0,0 +1,107 @@
class Api::V1::Issues::CreateService < ApplicationService
include ActiveModel::Model
attr_reader :project, :created_issue, :current_user
attr_reader :status_id, :priority_id, :milestone_id, :branch_name, :start_date, :due_date, :subject, :description
attr_reader :issue_tag_ids, :assigner_ids, :attachment_ids
validates :subject, presence: true
validates :status_id, :priority_id, presence: true
validates :current_user, presence: true
def initialize(project, params, current_user = nil)
@project = project
@current_user = current_user
@status_id = params[:status_id]
@priority_id = params[:priority_id]
@milestone_id = params[:milestone_id]
@branch_name = params[:branch_name]
@start_date = params[:start_date]
@due_date = params[:due_date]
@subject = params[:subject]
@description = params[:description]
@issue_tag_ids = params[:issue_tag_ids]
@assigner_ids = params[:assigner_ids]
@attachment_ids = params[:attachment_ids]
end
def call
raise Error, errors.full_messages.join(", ") unless valid?
begin
ActiveRecord::Base.transaction do
check_issue_status
check_issue_priority
check_milestone if milestone_id.present?
load_assigners unless assigner_ids.blank?
load_attachments unless attachment_ids.blank?
load_issue_tags unless issue_tag_ids.blank?
load_participants
@created_issue = Issue.new(issue_attributes)
@created_issue.assigners = @assigners unless assigner_ids.blank?
@created_issue.attachments = @attachments unless attachment_ids.blank?
@created_issue.issue_tags = @issue_tags unless issue_tag_ids.blank?
@created_issue.participants = @participants
@created_issue.save!
project.del_project_issue_cache_delete_count # 把缓存里存储项目删除issue的个数清除掉
end
return @created_issue
rescue
raise Error, "服务器错误,请联系系统管理员!"
end
end
private
def check_issue_status
raise Error, "IssueStatus不存在" unless IssueStatus.find_by_id(status_id).present?
end
def check_issue_priority
raise Error, "IssuePriority不存在" unless IssuePriority.find_by_id(priority_id).present?
end
def check_milestone
raise Error, "Milestone不存在" unless Version.find_by_id(milestone_id).present?
end
def load_assigners
@assigners = User.where(id: assigner_ids)
end
def load_issue_tags
@issue_tags = IssueTag.where(id: issue_tag_ids)
end
def load_attachments
@attachments = Attachment.where(id: attachment_ids)
end
def load_participants
@participants = User.where(id: assigner_ids).or(User.where(id: current_user.id))
end
def issue_attributes
issue_attributes = {
subject: subject,
project_id: project.id,
author_id: current_user.id,
tracker_id: Tracker.first.id,
status_id: status_id,
priority_id: priority_id,
project_issues_index: (project.get_last_project_issues_index + 1),
issue_type: "1",
issue_classify: "Issue"
}
issue_attributes.merge!({description: description}) if description.present?
issue_attributes.merge!({fixed_version_id: milestone_id}) if milestone_id.present?
issue_attributes.merge!({start_date: start_date}) if start_date.present?
issue_attributes.merge!({due_date: due_date}) if due_date.present?
issue_attributes.merge!({branch_name: branch_name}) if branch_name.present?
issue_attributes
end
end

View File

@ -6,14 +6,15 @@ class Api::V1::Issues::ListService < ApplicationService
attr_accessor :queried_issues attr_accessor :queried_issues
validates :category, inclusion: {in: %w(all opened closed), message: "请输入正确的Category"} validates :category, inclusion: {in: %w(all opened closed), message: "请输入正确的Category"}
validates :participant_category, inclusion: {in: %w(all aboutme authoredme assignedme atme), message: "请输入正确的ParticipantCategory"}
validates :sort_by, inclusion: {in: Issue.column_names, message: '请输入正确的SortBy'}, allow_blank: true validates :sort_by, inclusion: {in: Issue.column_names, message: '请输入正确的SortBy'}, allow_blank: true
validates :sort_direction, inclusion: {in: %w(asc desc), message: '请输入正确的SortDirection'}, allow_blank: true validates :sort_direction, inclusion: {in: %w(asc desc), message: '请输入正确的SortDirection'}, allow_blank: true
validates :current_user, presence: true
def initialize(project, params, current_user=nil) def initialize(project, params, current_user=nil)
puts params
@project = project @project = project
@category = params[:category] || 'all' @category = params[:category] || 'all'
@participant_category = params[:participant_category] @participant_category = params[:participant_category] || 'all'
@keyword = params[:keyword] @keyword = params[:keyword]
@author_id = params[:author_id] @author_id = params[:author_id]
@issue_tag_ids = params[:issue_tag_ids] @issue_tag_ids = params[:issue_tag_ids]

View File

@ -0,0 +1,42 @@
json.(issue, :id, :subject, :project_issues_index, :description, :branch_name, :start_date, :due_date)
json.created_at issue.created_on.strftime("%Y-%m-%d %H:%M")
json.updated_at issue.updated_on.strftime("%Y-%m-%d %H:%M")
json.tags issue.issue_tags.each do |tag|
json.partial! "api/v1/issues/issue_tags/simple_detail", locals: {tag: tag}
end
json.status do
if issue.issue_status.present?
json.partial! "api/v1/issues/statues/simple_detail", locals: {status: issue.issue_status}
else
json.nil!
end
end
json.priority do
if issue.priority.present?
json.partial! "api/v1/issues/issue_priorities/simple_detail", locals: {priority: issue.priority}
else
json.nil!
end
end
json.milestone do
if issue.version.present?
json.partial! "api/v1/issues/milestones/simple_detail", locals: {milestone: issue.version}
else
json.nil!
end
end
json.author do
if issue.user.present?
json.partial! "api/v1/users/simple_user", locals: {user: issue.user}
else
json.nil!
end
end
json.assigners issue.assigners.each do |assigner|
json.partial! "api/v1/users/simple_user", locals: {user: assigner}
end
json.participants issue.participants.each do |participant|
json.partial! "api/v1/users/simple_user", locals: {user: participant}
end
json.comment_journals_count issue.comment_journals.size
json.operate_journals_count issue.operate_journals.size

View File

@ -1,6 +1,6 @@
json.(issue, :id, :subject, :project_issues_index) json.(issue, :id, :subject, :project_issues_index)
json.created_at issue.created_on.strftime("%Y/%m/%d %H:%M") json.created_at issue.created_on.strftime("%Y-%m-%d %H:%M")
json.updated_at issue.updated_on.strftime("%Y/%m/%d %H:%M") json.updated_at issue.updated_on.strftime("%Y-%m-%d %H:%M")
json.tags issue.issue_tags.each do |tag| json.tags issue.issue_tags.each do |tag|
json.partial! "api/v1/issues/issue_tags/simple_detail", locals: {tag: tag} json.partial! "api/v1/issues/issue_tags/simple_detail", locals: {tag: tag}
end end

View File

@ -0,0 +1 @@
json.partial! "api/v1/issues/detail", locals: {issue: @object_result}

View File

@ -1,4 +1,6 @@
json.total_count @issues.total_count json.total_count @issues.total_count
json.opened_count @issues.opened.size
json.closed_count @issues.closed.size
json.issues @issues.each do |issue| json.issues @issues.each do |issue|
json.partial! "simple_detail", locals: {issue: issue} json.partial! "simple_detail", locals: {issue: issue}
end end

View File

@ -0,0 +1 @@
json.(priority, :id, :name)

View File

@ -1,4 +1,4 @@
json.total_count @priorities.total_count json.total_count @priorities.total_count
json.priorities @priorities.each do |priority| json.priorities @priorities.each do |priority|
json.(priority, :id, :name) json.partial! "simple_detail", locals: {priority: priority}
end end

View File

@ -0,0 +1 @@
json.partial! "api/v1/issues/detail", locals: {issue: @issue}

View File

@ -0,0 +1 @@
json.(status, :id, :name)

View File

@ -1,4 +1,4 @@
json.total_count @statues.total_count json.total_count @statues.total_count
json.statues @statues.each do |status| json.statues @statues.each do |status|
json.(status, :id, :name) json.partial! "simple_detail", locals: {status: status}
end end

View File

@ -0,0 +1,22 @@
# 执行示例 bundle exec rake sync_version_issues:update_issues
# 线上环境执行示例 RAILS_ENV=production bundle exec rake sync_version_issues:update_issues
namespace :fix_issue_project_issues_index do
desc "update issue project_issues_index"
task update_issues: :environment do
puts "____________fix start________________"
Issue.update_all(project_issues_index: nil)
Issue.where(project_issues_index: nil).group(:project_id).count.each do |pid, count|
p = Project.find_by_id(pid)
issues = p.issues.order(created_on: :asc)
issues.find_each.with_index do |issue, index|
issue.update_column(:project_issues_index, index+1)
end
end
puts "____________fix end________________"
end
end