diff --git a/app/controllers/api/pm/issues_controller.rb b/app/controllers/api/pm/issues_controller.rb index cdf5f1d7d..472921dc8 100644 --- a/app/controllers/api/pm/issues_controller.rb +++ b/app/controllers/api/pm/issues_controller.rb @@ -130,12 +130,26 @@ class Api::Pm::IssuesController < Api::Pm::BaseController [['requirement', 1], ['task', 2], ['bug', 3]].each do |type| p.workbook.add_worksheet(:name => type[0]) do |sheet| @issues = Issue.where(pm_project_id: params[:pm_project_id], pm_issue_type: type[1]) - sheet.add_row ["标题", "正文", "创建者", "创建时间", "修改者", "更新时间", "状态", "负责人", "优先级", "标记", "开始时间","结束时间", "预估工时"] + sheet.add_row ["ID", "标题", "正文", "创建者", "创建时间", "修改者", "更新时间", "状态", "负责人", "优先级", "标记", "开始时间","结束时间", "预估工时"] @issues.each do |issue| - sheet.add_row [issue.subject, issue.description, issue.user.try(:login), issue.created_on.strftime("%Y-%m-%d %H:%M:%S"), issue.changer.try(:login), issue.updated_on.strftime("%Y-%m-%d %H:%M:%S"), issue.status_id, issue.assigners.pluck(:login).join(","), issue.priority_id, issue.issue_tags.pluck(:name, :color).join(","), issue.start_date.present? ? issue.start_date.strftime("%Y-%m-%d") : "", issue.due_date.present? ? issue.due_date.strftime("%Y-%m-%d") : "", issue.time_scale] + sheet.add_row [issue.id, issue.subject, issue.description, issue.user.try(:login), issue.created_on.strftime("%Y-%m-%d %H:%M:%S"), issue.changer.try(:login), issue.updated_on.strftime("%Y-%m-%d %H:%M:%S"), issue.status_id, issue.assigners.pluck(:login).join(","), issue.priority_id, issue.issue_tags.pluck(:name, :color).join(","), issue.start_date.present? ? issue.start_date.strftime("%Y-%m-%d") : "", issue.due_date.present? ? issue.due_date.strftime("%Y-%m-%d") : "", issue.time_scale] end end end + p.workbook.add_worksheet(:name => 'leaf_relations') do |sheet| + leaf_issues = Issue.where(pm_project_id: params[:pm_project_id]).where.not(root_id: nil) + sheet.add_row ["ID", "父工作项ID"] + leaf_issues.each do |issue| + sheet.add_row [issue.id, issue.root_id] + end + end + p.workbook.add_worksheet(:name => 'link_relations') do |sheet| + links = PmLink.joins(:linkable_issue).where(issues: {pm_project_id: params[:pm_project_id]}) + sheet.add_row ["ID", "被关联工作项ID"] + links.each do |link| + sheet.add_row [link.linkable_id, link.be_linkable_id] + end + end p.serialize('public/导出工作项.xlsx') end @@ -143,50 +157,78 @@ class Api::Pm::IssuesController < Api::Pm::BaseController end def import - return render_error('请上传正确的文件') if params[:file].blank? || !params[:file].is_a?(ActionDispatch::Http::UploadedFile) - return render_error('请输入正确的项目ID.') if params[:pm_project_id].blank? - return render_error('请输入正确的组织ID.') if params[:organization_id].blank? - types = {requirement: 1, task: 2, bug: 3} - doc = SimpleXlsxReader.open(params[:file].tempfile) - doc.sheets.each do |sheet| - type = types["#{sheet.name}".to_sym] - sheet.rows.each.with_index do |row, index| - next if index == 0 - issue = Issue.new(issue_classify: "issue", project_id: 0, pm_project_id: params[:pm_project_id], pm_issue_type: type, tracker_id: Tracker.first.id) - issue.subject = row[0] - issue.description = row[1] - author = User.find_by(login: row[2]) || User.first - issue.user = author - issue.created_on = row[3] - changer = User.find_by(login: row[4]) || User.first - issue.changer = changer - issue.updated_on = row[5] - issue.status_id = row[6].to_i - if row[7].present? - row[7].split(',').each do |a| - u = User.find_by(login: a) - next unless u.present? - issue.assigners << u - end - end - issue.priority_id = row[8] - if row[9].present? - row[9].split(',').each_slice(2).to_a.each do |t| - tag = IssueTag.find_by(project_id: 0, organization_id: params[:organization_id], name: t[0]) - if tag.present? - issue.issue_tags << tag - else - tag = IssueTag.create(project_id: 0,organization_id: params[:organization_id], name: t[0], color: t[1]) - issue.issue_tags << tag + begin + return render_error('请上传正确的文件') if params[:file].blank? || !params[:file].is_a?(ActionDispatch::Http::UploadedFile) + return render_error('请输入正确的项目ID.') if params[:pm_project_id].blank? + return render_error('请输入正确的组织ID.') if params[:organization_id].blank? + ActiveRecord::Base.transaction do + types = {requirement: 1, task: 2, bug: 3} + doc = SimpleXlsxReader.open(params[:file].tempfile) + doc.sheets.each do |sheet| + case sheet.name + when 'requirement', 'task', 'bug' + + type = types["#{sheet.name}".to_sym] + + sheet.rows.each.with_index do |row, index| + next if index == 0 + issue = Issue.new(issue_classify: "issue", project_id: 0, pm_project_id: params[:pm_project_id], pm_issue_type: type, tracker_id: Tracker.first.id) + issue.fake_id = row[0] + issue.subject = row[1] + issue.description = row[2] + author = User.find_by(login: row[3]) || User.where(admin: true).first + issue.user = author + issue.created_on = row[4] + changer = User.find_by(login: row[5]) || User.where(admin: true).first + issue.changer = changer + issue.updated_on = row[6] + issue.status_id = row[7].to_i + if row[8].present? + row[8].split(',').each do |a| + u = User.find_by(login: a) + next unless u.present? + issue.assigners << u + end + end + issue.priority_id = row[9] + if row[10].present? + row[10].split(',').each_slice(2).to_a.each do |t| + tag = IssueTag.find_by(project_id: 0, organization_id: params[:organization_id], name: t[0]) + if tag.present? + issue.issue_tags << tag + else + tag = IssueTag.create(project_id: 0,organization_id: params[:organization_id], name: t[0], color: t[1]) + issue.issue_tags << tag + end + end + end + issue.start_date = row[11] + issue.due_date = row[12] + issue.time_scale = row[13] + issue.save! + end + when 'leaf_relations' + sheet.rows.each.with_index do |row, index| + next if index == 0 + children_issue = Issue.where(fake_id: row[0]).last + parent_issue = Issue.where(fake_id: row[1]).last + next if children_issue.blank? || parent_issue.blank? + children_issue.update_column(:root_id, parent_issue.id) + end + when 'link_relations' + sheet.rows.each.with_index do |row, index| + next if index == 0 + link_issue = Issue.where(fake_id: row[0]).last + be_link_issue = Issue.where(fake_id: row[1]).last + next if link_issue.blank? || be_link_issue.blank? + PmLink.create!(linkable_type: 'Issue', linkable_id: link_issue.id, be_linkable_type: 'Issue', be_linkable_id: be_link_issue.id) end end + end - issue.start_date = row[10] - issue.due_date = row[11] - issue.time_scale = row[12] - issue.save end - + rescue + return render_error('导入失败,请上传正确格式的excel文件') end end diff --git a/app/models/pm_link.rb b/app/models/pm_link.rb index 91962bf7b..e45578158 100644 --- a/app/models/pm_link.rb +++ b/app/models/pm_link.rb @@ -18,6 +18,9 @@ class PmLink < ApplicationRecord belongs_to :linkable, polymorphic: true + belongs_to :be_linkable, polymorphic: true + belongs_to :linkable_issue, -> {where(pm_links: {linkable_type: 'Issue'})}, foreign_key: 'linkable_id', class_name: 'Issue' + belongs_to :be_linkable_issue, -> {where(pm_links: {be_linkable_type: 'Issue'})}, foreign_key: 'be_linkable_id', class_name: 'Issue' def be_linkable be_linkable_type.constantize.find be_linkable_id diff --git a/db/migrate/20240826084717_add_fake_id_to_issues.rb b/db/migrate/20240826084717_add_fake_id_to_issues.rb new file mode 100644 index 000000000..de9e30152 --- /dev/null +++ b/db/migrate/20240826084717_add_fake_id_to_issues.rb @@ -0,0 +1,5 @@ +class AddFakeIdToIssues < ActiveRecord::Migration[5.2] + def change + add_column :issues, :fake_id, :integer + end +end