diff --git a/app/controllers/api/v1/issues/milestones_controller.rb b/app/controllers/api/v1/issues/milestones_controller.rb index bb503390..79b1aa15 100644 --- a/app/controllers/api/v1/issues/milestones_controller.rb +++ b/app/controllers/api/v1/issues/milestones_controller.rb @@ -1,32 +1,67 @@ class Api::V1::Issues::MilestonesController < Api::V1::BaseController - before_action :require_public_and_member_above, only: [:index] + before_action :require_public_and_member_above + before_action :load_milestone, only: [:show, :update, :destroy] # 里程碑列表 def index if params[:only_name] - @milestones = @project.versions + @milestones = @project.versions.select(:id, :name) + @milestones = @milestones.ransack(name_or_description_cont: params[:keyword]).result if params[:keyword].present? + @milestones = kaminary_select_paginate(@milestones) else - @milestones = @project.versions.includes(:issues) + @milestones = @project.versions.includes(:issues, :closed_issues, :opened_issues) + @milestones = params[:category] == "closed" ? @milestones.closed : @milestones.opening + @milestones = @milestones.ransack(name_or_description_cont: params[:keyword]).result if params[:keyword].present? + @milestones = kaminari_paginate(@milestones) end - @milestones = @milestones.ransack(name_or_description_cont: params[:keyword]).result if params[:keyword].present? - @milestones = kaminary_select_paginate(@milestones) end + def create + @milestone = @project.versions.new(milestone_params) + if @milestone.save! + render_ok + else + render_error(@milestone.errors.full_messages.join(",")) + end + end + # 里程碑详情 def show - end - - def create + @object_results = Api::V1::Issues::Milestones::DetailIssuesService.call(@project, @milestone, query_params, current_user) + @closed_issues_count = @object_results.closed.size + @opened_issues_count = @object_results.opened.size + @issues = kaminari_paginate(@object_results) end def update + @milestone.attributes = milestone_params + if @milestone.save! + render_ok + else + render_error(@milestone.errors.full_messages.join(",")) + end end def destroy + if @milestone.destroy! + render_ok + else + render_error("删除里程碑失败!") + end end - private - + def milestone_params + params.permit(:name, :description, :effective_date) + end + + def query_params + params.permit(:category, :author_id, :assigner_id, :sort_by, :sort_direction, :issue_tag_ids => []) + end + + def load_milestone + @milestone = @project.versions.find_by_id(params[:id]) + return render_not_found('里程碑不存在!') unless @milestone.present? + end end \ No newline at end of file diff --git a/app/models/version.rb b/app/models/version.rb index 41256833..fab193b9 100644 --- a/app/models/version.rb +++ b/app/models/version.rb @@ -28,6 +28,9 @@ class Version < ApplicationRecord has_many :issues, class_name: "Issue", foreign_key: "fixed_version_id" belongs_to :user, optional: true + has_many :opened_issues, -> {where(issue_classify: "Issue").where.not(status_id: 5)}, class_name: "Issue", foreign_key: :fixed_version_id + has_many :closed_issues, -> {where(issue_classify: "Issue", status_id: 5)}, class_name: "Issue", foreign_key: :fixed_version_id + scope :version_includes, ->{includes(:issues, :user)} scope :closed, ->{where(status: 'closed')} scope :opening, ->{where(status: 'open')} @@ -43,6 +46,11 @@ class Version < ApplicationRecord after_create :send_create_message_to_notice_system after_save :send_update_message_to_notice_system + def issue_percent + issues_total_count = opened_issues.size + closed_issues.size + issues_total_count.zero? ? 0.0 : closed_issues.size.to_f / issues_total_count + end + def version_user User.select(:login, :lastname,:firstname, :nickname)&.find_by_id(self.user_id) end @@ -53,6 +61,6 @@ class Version < ApplicationRecord end def send_update_message_to_notice_system - SendTemplateMessageJob.perform_later('ProjectMilestoneCompleted', self.id) if Site.has_notice_menu? && self.percent == 1.0 + SendTemplateMessageJob.perform_later('ProjectMilestoneCompleted', self.id) if Site.has_notice_menu? && self.issue_percent == 1.0 end end diff --git a/app/services/api/v1/issues/batch_update_service.rb b/app/services/api/v1/issues/batch_update_service.rb index ffa1ba7d..cf09650c 100644 --- a/app/services/api/v1/issues/batch_update_service.rb +++ b/app/services/api/v1/issues/batch_update_service.rb @@ -20,7 +20,9 @@ class Api::V1::Issues::BatchUpdateService < ApplicationService raise Error, errors.full_messages.join(", ") unless valid? ActiveRecord::Base.transaction do @issues.each do |issue| - Api::V1::Issues::UpdateService.call(project, issue, params, current_user) + if issue.issue_classify == "Issue" + Api::V1::Issues::UpdateService.call(project, issue, params, current_user) + end end return true diff --git a/app/services/api/v1/issues/milestones/detail_issues_service.rb b/app/services/api/v1/issues/milestones/detail_issues_service.rb new file mode 100644 index 00000000..1328805b --- /dev/null +++ b/app/services/api/v1/issues/milestones/detail_issues_service.rb @@ -0,0 +1,59 @@ +class Api::V1::Issues::Milestones::DetailIssuesService < ApplicationService + include ActiveModel::Model + + attr_reader :project, :category, :author_id, :assigner_id, :issue_tag_ids, :sort_by, :sort_direction, :current_user + attr_accessor :queried_issues + + validates :category, inclusion: {in: %w(all opened closed), message: "请输入正确的Category"} + 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 :current_user, presence: true + + def initialize(project, milestone, params, current_user=nil) + @project = project + @milestone = milestone + @category = params[:category] || 'all' + @author_id = params[:author_id] + @assigner_id = params[:assigner_id] + @issue_tag_ids = params[:issue_tag_ids] + @sort_by = params[:sort_by].present? ? params[:sort_by] : 'updated_on' + @sort_direction = (params[:sort_direction].present? ? params[:sort_direction] : 'desc').downcase + @current_user = current_user + end + + def call + raise Error, errors.full_messages.join(", ") unless valid? + begin + issue_query_data + + queried_issues + rescue + raise Error, "服务器错误,请联系系统管理员!" + end + end + + private + def issue_query_data + issues = @milestone.issues.issue_issue + + case category + when 'closed' + issues = issues.closed + when 'opened' + issues = issues.opened + end + + # author_id + issues = issues.where(author_id: author_id) if author_id.present? + + # assigner_id + issues = issues.joins(:assigners).where(users: {id: assigner_id}).or(issues.where(assigned_to_id: assigner_id)) if assigner_id.present? + + scope = issues.includes(:priority, :issue_status, :user, :assigners, :version, :issue_tags, :comment_journals) + + scope = scope.reorder("issues.#{sort_by} #{sort_direction}").distinct + + @queried_issues = scope + end + +end \ No newline at end of file diff --git a/app/views/api/v1/issues/milestones/_detail.json.jbuilder b/app/views/api/v1/issues/milestones/_detail.json.jbuilder new file mode 100644 index 00000000..a7d66ae2 --- /dev/null +++ b/app/views/api/v1/issues/milestones/_detail.json.jbuilder @@ -0,0 +1,6 @@ +json.(milestone, :id, :name, :description, :effective_date, :status) +json.issues_count milestone.opened_issues.size + milestone.closed_issues.size +json.close_issues_count milestone.closed_issues.size +json.percent milestone.issue_percent +json.created_at milestone.created_on.strftime("%Y-%m-%d %H:%M") +json.updated_on milestone.updated_on.strftime("%Y-%m-%d %H:%M") diff --git a/app/views/api/v1/issues/milestones/index.json.jbuilder b/app/views/api/v1/issues/milestones/index.json.jbuilder index 012549bd..cea2b43b 100644 --- a/app/views/api/v1/issues/milestones/index.json.jbuilder +++ b/app/views/api/v1/issues/milestones/index.json.jbuilder @@ -2,5 +2,7 @@ json.total_count @milestones.total_count json.milestones @milestones.each do |milestone| if params[:only_name] json.partial! "simple_detail", locals: {milestone: milestone} + else + json.partial! "detail", locals: {milestone: milestone} end end \ No newline at end of file diff --git a/app/views/api/v1/issues/milestones/show.json.jbuilder b/app/views/api/v1/issues/milestones/show.json.jbuilder new file mode 100644 index 00000000..01632e9d --- /dev/null +++ b/app/views/api/v1/issues/milestones/show.json.jbuilder @@ -0,0 +1,11 @@ +json.milestone do + json.partial! "detail", locals: {milestone: @milestone} +end +json.total_issues_count @issues.total_count +json.closed_issues_count @closed_issues_count +json.opened_issues_count @opened_issues_count +json.issues @issues.each do |issue| + if issue.issue_classify == "Issue" + json.partial! "api/v1/issues/simple_detail", locals: {issue: issue} + end +end \ No newline at end of file