diff --git a/app/controllers/issues_controller.rb b/app/controllers/issues_controller.rb index de055777b..a11662af4 100644 --- a/app/controllers/issues_controller.rb +++ b/app/controllers/issues_controller.rb @@ -1,7 +1,245 @@ class IssuesController < ApplicationController before_action :require_login + before_action :set_project + before_action :check_project_public, only: [:index ,:show] + before_action :check_issue_permission, except: [:index, :show] + before_action :set_issue, only: [:edit, :update, :destroy, :show] + def index + end + def new + @issue_chosen = issue_left_chosen(@project, nil) + end + + def create + if params[:subject].blank? + normal_status(-1, "标题不能为空") + else + issue_params = { + subject: params[:subject], + description: params[:description], + is_private: params[:is_private], + assigned_to_id: params[:assigned_to_id], + tracker_id: params[:tracker_id], + status_id: params[:status_id], + priority_id: params[:priority_id], + fixed_version_id: params[:fixed_version_id], + start_date: params[:start_date].to_s.to_date, + due_date: params[:due_date].to_s.to_date, + estimated_hours: params[:estimated_hours], + done_ratio: params[:done_ratio] + } + @issue = Issue.new(issue_params.merge(author_id: current_user.id, project_id: @project.id)) + if @issue.save! + if params[:attachment_ids].present? + params[:attachment_ids].each do |id| + attachment = Attachment.select(:id, :container_id, :container_type)&.find_by_id(id) + unless attachment.blank? + attachment.container = @issue + attachment.save + end + end + end + if params[:assigned_to_id].present? + Tiding.create!(user_id: params[:assigned_to_id], trigger_user_id: current_user.id, + container_id: @issue.id, container_type: 'Issue', + parent_container_id: @project.id, parent_container_type: "Project", + tiding_type: 'issue', status: 0) + end + normal_status(0, "创建成功") + else + normal_status(-1, "创建失败") + end + end + + end + + def edit + @issue_chosen = issue_left_chosen(@project, @issue.id) + @issue_attachments = @issue.attachments + end + + def update + issue_params = { + subject: params[:subject], + description: params[:description], + is_private: params[:is_private], + assigned_to_id: params[:assigned_to_id], + tracker_id: params[:tracker_id], + status_id: params[:status_id], + priority_id: params[:priority_id], + fixed_version_id: params[:fixed_version_id], + start_date: params[:start_date].to_s.to_date, + due_date: params[:due_date].to_s.to_date, + estimated_hours: params[:estimated_hours], + done_ratio: params[:done_ratio] + } + + if @issue.update_attributes(issue_params) + issue_files = params[:attachment_ids] + change_files = false + issue_file_ids = [] + if issue_files.present? + issue_attachments = @issue&.attachments + issue_file_ids = issue_attachments&.pluck(:id) + left_file_ids = issue_file_ids - issue_files + new_file_ids = issue_files - issue_file_ids + if left_file_ids.size > 0 + change_files = true + issue_attachments.where(id: left_file_ids).delete_all + end + if new_file_ids.size > 0 + change_files = true + new_file_ids.each do |id| + attachment = Attachment.select(:id, :container_id, :container_type)&.find_by_id(id) + unless attachment.blank? + attachment.container = @issue + attachment.save + end + end + end + end + + @issue.create_journal_detail(change_files, issue_files, issue_file_ids) + normal_status(0, "更新成功") + else + normal_status(-1, "更新失败") + end + + end + + def show + @issue_attachments = @issue.attachments + @issue_user = @issue.user + @issue_assign_to = @issue.get_assign_user + @journals = @issue.journals.journal_includes.order("created_on desc") + end + + def destroy + if @issue.destroy + normal_status(0, "删除成功") + else + normal_status(-1, "删除失败") + end + + end + + + private + def set_project + @project = Project.find_by_id(params[:project_id]) + unless @project.present? + normal_status(-1, "项目不存在") + end + end + + def check_project_public + unless @project.is_public || @project.member?(current_user) || current_user.admin? + normal_status(-1, "您没有权限") + end + end + + def set_issue + @issue = Issue.find_by_id(params[:id]) + unless @issue.present? + normal_status(-1, "标签不存在") + end + end + + def check_issue_permission + unless @project.member?(current_user) || current_user.admin? + normal_status(-1, "您没有权限") + end + end + + def issue_left_chosen(project,issue_id) + issue_info = Array.new(9) + if issue_id.present? + select_arrays = [:assigned_to_id, :tracker_id, :status_id, :priority_id, :fixed_version_id, :start_date, :due_date, :estimated_hours, :done_ratio] + issue_info = Issue.select(select_arrays).where(id: issue_id).pluck(select_arrays) + issue_info = issue_info[0] + end + project_members = project.members_user_infos + project_members_info = [] #指派给 + project_members.each do |member| + real_name = member[2] + member[3] + unless real_name.present? + real_name = member[1] + end + user_id = member[0] + is_chosen = ((member[0].to_s == issue_info[0].to_s) ? "1" : "0") + member_info = {id: user_id, name: real_name, is_chosen: is_chosen} + project_members_info.push(member_info) + end + + tracker_info = project.trackers&.pluck(:id, :name, :position) + new_tracker_info = [] #类型 + if tracker_info.size > 0 + tracker_info.each do |t| + is_chosen = (t[0] == issue_info[1]) ? "1" : "0" + new_tracker = {id: t[0], name: t[1], position: t[2], is_chosen: is_chosen} + new_tracker_info.push(new_tracker) + end + end + + + issue_status = IssueStatus&.pluck(:id,:name,:position) + new_status_info = [] #缺陷类型 + if issue_status.size > 0 + issue_status.each do |t| + is_chosen = (t[0] == issue_info[2]) ? "1" : "0" + new_issue = {id: t[0], name: t[1], position: t[2], is_chosen: is_chosen} + new_status_info.push(new_issue) + end + end + + + issue_priority = project.issue_tags&.pluck(:id,:title, :color) + new_priority_info = [] #issue标签,(优先程度) + if issue_priority.size > 0 + issue_priority.each do |t| + is_chosen = (t[0] == issue_info[3]) ? "1" : "0" + new_issue = {id: t[0], name: t[1], color: t[2], is_chosen: is_chosen} + new_priority_info.push(new_issue) + end + end + + + issue_versions = project.versions&.pluck(:id,:name, :status) + new_version_info = [] #issue里程碑 + if issue_versions.size > 0 + issue_versions.each do |t| + is_chosen = (t[0] == issue_info[4]) ? "1" : "0" + new_issue = {id: t[0], name: t[1], status: t[2], is_chosen: is_chosen} + new_version_info.push(new_issue) + end + end + + issue_done_ratio = %w(0 10 20 30 40 50 60 70 80 90 100) + new_done_info = [] #完成度 + if issue_done_ratio.size > 0 + issue_done_ratio.each do |t| + is_chosen = (t == issue_info[8].to_s) ? "1" : "0" + new_issue = {ratio: (t.to_s + "%"), is_chosen: is_chosen} + new_done_info.push(new_issue) + end + end + + + { + "assign_user": project_members_info, + "tracker": new_tracker_info, + "issue_status": new_status_info, + "issue_tag": new_priority_info, + "issue_version": new_version_info, + "start_date": issue_info[5], + "due_date": issue_info[6], + "estimated_hours": issue_info[7], + "done_ratio": new_done_info + } + + end end \ No newline at end of file diff --git a/app/controllers/tidings_controller.rb b/app/controllers/tidings_controller.rb index 5acffcb16..c6a945130 100644 --- a/app/controllers/tidings_controller.rb +++ b/app/controllers/tidings_controller.rb @@ -20,6 +20,8 @@ class TidingsController < ApplicationController tidings = tidings.where(tiding_type: tiding_types) if tiding_types.present? tidings = tidings.where(container_type: 'JoinCourse') if params[:type] == 'course_apply' + tidings = tidings.where(container_type: 'Issue') if params[:type] == 'issue' + @course_apply_count = tidings.where("created_at > '#{@onclick_time}'").where(container_type: 'JoinCourse').count tidings = tidings.where(container_type: 'ProjectPackage') if params[:type] == 'project_package' diff --git a/app/models/commit.rb b/app/models/commit.rb new file mode 100644 index 000000000..d11672cd3 --- /dev/null +++ b/app/models/commit.rb @@ -0,0 +1,4 @@ +class Commit < ApplicationRecord + belongs_to :project, foreign_key: :project_id + +end \ No newline at end of file diff --git a/app/models/commit_issue.rb b/app/models/commit_issue.rb new file mode 100644 index 000000000..b7947f69c --- /dev/null +++ b/app/models/commit_issue.rb @@ -0,0 +1,4 @@ +class CommitIssue < ApplicationRecord + belongs_to :issue, foreign_key: :issue_id + +end \ No newline at end of file diff --git a/app/models/issue.rb b/app/models/issue.rb index f3d54f98b..8f8ccceea 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -2,12 +2,44 @@ class Issue < ApplicationRecord belongs_to :project belongs_to :tracker belongs_to :issue_tag, foreign_key: :priority_id - belongs_to :version, foreign_key: :fixed_version_id - belongs_to :user,optional: true + belongs_to :version, foreign_key: :fixed_version_id,optional: true + belongs_to :user,optional: true, foreign_key: :author_id + belongs_to :issue_status, foreign_key: :status_id,optional: true + has_many :commit_issues + has_many :attachments, as: :container, dependent: :destroy + has_many :memos + has_many :journals + has_many :journal_details, through: :journals scope :issue_includes, ->{includes(:user)} + def get_assign_user User.select(:login, :lastname,:firstname, :nickname)&.find_by_id(self.assigned_to_id) end + + def create_journal_detail(change_files, issue_files, issue_file_ids) + journal = Journal.where(journalized_id: self.id, journalized_type: "Issue", user_id: self.author_id, notes: [nil,""]) + if journal.present? + journal.update_all(created_on: Time.now) + journal = journal.last + else + journal_params = { + journalized_id: self.id, journalized_type: "Issue", user_id: self.author_id + } + journal = Journal.new journal_params + journal.save + end + if change_files + journal.journal_details.create(property: "attachment", prop_key: "#{issue_files.size}", old_value: issue_file_ids, value: issue_files) + end + + change_values = %w(subject description is_private assigned_to_id tracker_id status_id priority_id fixed_version_id start_date due_date estimated_hours done_ratio) + change_values.each do |at| + if self.send("saved_change_to_#{at}?") + journal.journal_details.create(property: "attr", prop_key: "#{at}", old_value: self.send("#{at}_before_last_save"), value: self.send(at)) + end + end + end + end \ No newline at end of file diff --git a/app/models/issue_priority.rb b/app/models/issue_priority.rb new file mode 100644 index 000000000..6b815f420 --- /dev/null +++ b/app/models/issue_priority.rb @@ -0,0 +1,3 @@ +class IssuePriority < ApplicationRecord + has_many :issues +end \ No newline at end of file diff --git a/app/models/issue_status.rb b/app/models/issue_status.rb new file mode 100644 index 000000000..82bc62abf --- /dev/null +++ b/app/models/issue_status.rb @@ -0,0 +1,4 @@ +class IssueStatus < ApplicationRecord + has_many :issues + belongs_to :project, optional: true +end \ No newline at end of file diff --git a/app/models/issue_tag.rb b/app/models/issue_tag.rb index 47193addb..4f1ac9757 100644 --- a/app/models/issue_tag.rb +++ b/app/models/issue_tag.rb @@ -1,4 +1,4 @@ class IssueTag < ApplicationRecord has_many :issues - belongs_to :projects, optional: true + belongs_to :project, optional: true end diff --git a/app/models/journal.rb b/app/models/journal.rb index 25c1e2498..dd42bc743 100644 --- a/app/models/journal.rb +++ b/app/models/journal.rb @@ -1,4 +1,7 @@ class Journal < ApplicationRecord belongs_to :user belongs_to :issue, foreign_key: :journalized_id + has_many :journal_details, :dependent => :delete_all + + scope :journal_includes, ->{includes(:user, :journal_details)} end \ No newline at end of file diff --git a/app/models/journal_detail.rb b/app/models/journal_detail.rb new file mode 100644 index 000000000..c97bdf378 --- /dev/null +++ b/app/models/journal_detail.rb @@ -0,0 +1,3 @@ +class JournalDetail < ApplicationRecord + belongs_to :journal +end \ No newline at end of file diff --git a/app/models/member.rb b/app/models/member.rb index 70b7fe305..a9173cab1 100644 --- a/app/models/member.rb +++ b/app/models/member.rb @@ -5,4 +5,5 @@ class Member < ApplicationRecord has_many :member_roles, dependent: :destroy has_many :roles, through: :member_roles + end diff --git a/app/models/project.rb b/app/models/project.rb index 3b8d293de..e383003af 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -5,17 +5,22 @@ class Project < ApplicationRecord belongs_to :project_category , :counter_cache => true belongs_to :project_language , :counter_cache => true + has_many :commits + has_many :members has_many :manager_members, -> { joins(:roles).where(roles: { name: 'Manager' }) }, class_name: 'Member' has_one :project_score, dependent: :destroy has_one :repository, dependent: :destroy has_many :issue_tags + has_many :issue_statuses has_many :issues has_many :user_grades, dependent: :destroy has_many :attachments, as: :container, dependent: :destroy has_one :project_score, dependent: :destroy has_many :versions, -> { order("versions.effective_date DESC, versions.name DESC") }, dependent: :destroy + has_and_belongs_to_many :trackers, :order => "#{Tracker.table_name}.position" + after_create do SyncTrustieJob.perform_later("project", 1) if allow_sync_to_trustie? @@ -34,4 +39,9 @@ class Project < ApplicationRecord members.exists?(user_id: user.id) end + def members_user_infos + members.joins("left join users on members.user_id = users.id").select("users.id", "users.login","users.firstname","users.lastname") + .pluck("users.id", "users.login","users.lastname", "users.firstname") + end + end diff --git a/app/models/tracker.rb b/app/models/tracker.rb index f91ad92ee..a5202b26e 100644 --- a/app/models/tracker.rb +++ b/app/models/tracker.rb @@ -1,3 +1,4 @@ class Tracker < ApplicationRecord has_many :issues + has_and_belongs_to_many :projects end \ No newline at end of file diff --git a/app/views/issue_tags/edit.json.jbuilder b/app/views/issue_tags/edit.json.jbuilder index 72e2b14d9..7aa831920 100644 --- a/app/views/issue_tags/edit.json.jbuilder +++ b/app/views/issue_tags/edit.json.jbuilder @@ -1 +1,2 @@ +json.partial! "commons/success" json.extract! @issue_tag, :id, :title, :description, :color,:project_id \ No newline at end of file diff --git a/app/views/issue_tags/index.json.jbuilder b/app/views/issue_tags/index.json.jbuilder index 9e04a74d3..e71945841 100644 --- a/app/views/issue_tags/index.json.jbuilder +++ b/app/views/issue_tags/index.json.jbuilder @@ -1,3 +1,4 @@ +json.partial! "commons/success" json.issue_tags_count @issue_tags_size json.issue_tags do diff --git a/app/views/issues/_journal_item.json.jbuilder b/app/views/issues/_journal_item.json.jbuilder new file mode 100644 index 000000000..24c3d3356 --- /dev/null +++ b/app/views/issues/_journal_item.json.jbuilder @@ -0,0 +1,3 @@ +json.issue_id journal.journalized_id +json.notes journal.try(:notes) +json.created_at time_from_now(journal.created_on) \ No newline at end of file diff --git a/app/views/issues/edit.json.jbuilder b/app/views/issues/edit.json.jbuilder new file mode 100644 index 000000000..8de9d1576 --- /dev/null +++ b/app/views/issues/edit.json.jbuilder @@ -0,0 +1,10 @@ +json.partial! "commons/success" +json.extract! @issue, :id,:subject,:description,:is_private,:assigned_to_id,:tracker_id,:status_id,:priority_id,:fixed_version_id, + :start_date,:due_date,:estimated_hours,:done_ratio +json.issue_chosen @issue_chosen + +json.attachments do + json.array! @issue_attachments do |attachment| + json.partial! "attachments/attachment", attachment: attachment + end +end diff --git a/app/views/issues/new.json.jbuilder b/app/views/issues/new.json.jbuilder new file mode 100644 index 000000000..1f442f713 --- /dev/null +++ b/app/views/issues/new.json.jbuilder @@ -0,0 +1,2 @@ +json.partial! "commons/success" +json.issue_chosen @issue_chosen \ No newline at end of file diff --git a/app/views/issues/show.json.jbuilder b/app/views/issues/show.json.jbuilder new file mode 100644 index 000000000..cd1442a5f --- /dev/null +++ b/app/views/issues/show.json.jbuilder @@ -0,0 +1,25 @@ +json.partial! "commons/success" +json.extract! @issue, :id,:subject,:description,:is_private, :start_date,:due_date,:estimated_hours +json.created_at format_time(@issue.created_on) +json.assign_user_name @issue_assign_to.try(:show_real_name) +json.assign_user_login @issue_assign_to.try(:login) +json.author_name @issue_user.try(:show_real_name) +json.author_picture url_to_avatar(@issue_user) +json.tracker @issue.tracker.try(:name) +json.issue_status @issue.issue_status.try(:name) +json.priority @issue.issue_tag.try(:title) +json.version @issue.version.try(:title) +json.done_ratio @issue.done_ratio.to_s + "%" +json.attachments do + json.array! @issue_attachments do |attachment| + json.partial! "attachments/attachment_simple", locals: {attachment: attachment} + end +end + +json.issue_comments do + json.array! @journals do |journal| + json.partial! "issues/journal_item", journal: journal + end +end + + diff --git a/app/views/versions/edit.json.jbuilder b/app/views/versions/edit.json.jbuilder index 55e081dc6..c5e286457 100644 --- a/app/views/versions/edit.json.jbuilder +++ b/app/views/versions/edit.json.jbuilder @@ -1 +1,2 @@ +json.partial! "commons/success" json.extract! @version, :id,:name,:project_id,:description, :effective_date, :status, :sharing,:wiki_page_title diff --git a/app/views/versions/index.json.jbuilder b/app/views/versions/index.json.jbuilder index 71c640d8f..0a25e363b 100644 --- a/app/views/versions/index.json.jbuilder +++ b/app/views/versions/index.json.jbuilder @@ -1,3 +1,4 @@ +json.partial! "commons/success" json.versions_count @versions_size json.versions do diff --git a/app/views/versions/show.json.jbuilder b/app/views/versions/show.json.jbuilder index 52d275f9b..206b1faaf 100644 --- a/app/views/versions/show.json.jbuilder +++ b/app/views/versions/show.json.jbuilder @@ -1,3 +1,4 @@ +json.partial! "commons/success" json.issues_count @version_issues_size json.close_issues_count @close_issues_size json.user_name @version.version_user.try(:show_real_name) diff --git a/config/routes.rb b/config/routes.rb index 0f97eba11..caa90b8b3 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -33,6 +33,7 @@ Rails.application.routes.draw do resources :licenses, only: [:index, :show] resources :projects, only: [:index, :create, :show] do + resources :issues resources :issue_tags, only: [:create, :edit, :update, :destroy, :index] resources :versions do member do