diff --git a/app/controllers/api/v1/issues_controller.rb b/app/controllers/api/v1/issues_controller.rb new file mode 100644 index 000000000..1decf3421 --- /dev/null +++ b/app/controllers/api/v1/issues_controller.rb @@ -0,0 +1,23 @@ +class Api::V1::IssuesController < Api::V1::BaseController + + before_action :require_public_and_member_above, only: [:index] + + def index + @object_results = Api::V1::Issues::ListService.call(@project, query_params, current_user) + @issues = kaminari_paginate(@object_results) + end + + private + + def query_params + params.permit( + :category, + :participant_category, + :keyword, :author_id, + :milestone_id, :assigner_id, + :status_id, + :sort_by, :sort_direction, + :issue_tag_ids => []) + end + +end \ No newline at end of file diff --git a/app/services/api/v1/issues/list_service.rb b/app/services/api/v1/issues/list_service.rb new file mode 100644 index 000000000..1a7378598 --- /dev/null +++ b/app/services/api/v1/issues/list_service.rb @@ -0,0 +1,87 @@ +class Api::V1::Issues::ListService < ApplicationService + include ActiveModel::Model + + attr_reader :project, :category, :participant_category, :keyword, :author_id, :issue_tag_ids + attr_reader :milestone_id, :assigner_id, :status_id, :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 + + def initialize(project, params, current_user=nil) + puts params + @project = project + @category = params[:category] || 'all' + @participant_category = params[:participant_category] + @keyword = params[:keyword] + @author_id = params[:author_id] + @issue_tag_ids = params[:issue_tag_ids] + @milestone_id = params[:milestone_id] + @assigner_id = params[:assigner_id] + @status_id = params[:status_id] + @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 = @project.issues.issue_issue.joins(:journals).where.not(journals: {notes: nil}) + + case category + when 'closed' + issues = issues.closed + when 'opened' + issues = issues.opened + end + + case participant_category + when 'aboutme' # 关于我的 + issues = issues.joins(:participants, :issue_participants).where(issue_participants: {participant_type: %(authored assigned atme)},users: {id: current_user&.id}) + when 'authoredme' # 我创建的 + issues = issues.joins(:participants, :issue_participants).where(issue_participants: {participant_type: %(authored)},users: {id: current_user&.id}) + when 'assignedme' # 我负责的 + issues = issues.joins(:participants, :issue_participants).where(issue_participants: {participant_type: %(assigned)},users: {id: current_user&.id}) + when 'atme' # @我的 + issues = issues.joins(:participants, :issue_participants).where(issue_participants: {participant_type: %(atme)},users: {id: current_user&.id}) + end + + # author_id + issues = issues.where(author_id: author_id) if author_id.present? + + # issue_tag_ids + issues = issues.joins(:issue_tags).where(issue_tags: {id: issue_tag_ids}) unless issue_tag_ids.blank? + + # milestone_id + issues = issues.where(fixed_version_id: milestone_id) if milestone_id.present? + + # assigner_id + issues = issues.joins(:assigners).where(users: {id: assigner_id}) if assigner_id.present? + + # status_id + issues = issues.where(status_id: status_id) if status_id.present? + + # keyword + q = issues.ransack(subject_or_description_cont: keyword) + + scope = q.result.includes(:priority, :issue_status, :user, :assigners, :version, :issue_tags, :journals) + + + scope = scope.reorder("issues.#{sort_by} #{sort_direction}") + + @queried_issues = scope + end + +end \ No newline at end of file diff --git a/app/views/api/v1/issues/_simple_detail.json.jbuilder b/app/views/api/v1/issues/_simple_detail.json.jbuilder index e69de29bb..395086d59 100644 --- a/app/views/api/v1/issues/_simple_detail.json.jbuilder +++ b/app/views/api/v1/issues/_simple_detail.json.jbuilder @@ -0,0 +1,20 @@ +json.(issue, :id, :subject, :project_issues_index) +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_name issue.issue_status&.name +json.priority_name issue.priority&.name +json.milestone_name issue.version&.name +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.journals_count issue.journals.size \ No newline at end of file diff --git a/app/views/api/v1/issues/index.json.jbuilder b/app/views/api/v1/issues/index.json.jbuilder new file mode 100644 index 000000000..e0d6ae7bd --- /dev/null +++ b/app/views/api/v1/issues/index.json.jbuilder @@ -0,0 +1,4 @@ +# json.total_count @issues.total_count +json.issues @issues.each do |issue| + json.partial! "simple_detail", locals: {issue: issue} +end \ No newline at end of file diff --git a/app/views/api/v1/issues/issue_tags/_simple_detail.json.jbuilder b/app/views/api/v1/issues/issue_tags/_simple_detail.json.jbuilder index f0826fab7..8395a8e83 100644 --- a/app/views/api/v1/issues/issue_tags/_simple_detail.json.jbuilder +++ b/app/views/api/v1/issues/issue_tags/_simple_detail.json.jbuilder @@ -1 +1 @@ -json.(tag, :id, :name) \ No newline at end of file +json.(tag, :id, :name, :color) \ No newline at end of file