class IssuesController < ApplicationController
before_action :require_login , except : [ :index , :show ]
before_action :set_project
before_action :check_project_public , only : [ :index , :show , :copy , :index_chosen , :close_issue ]
before_action :check_issue_permission , except : [ :index , :show , :index_chosen ]
before_action :set_issue , only : [ :edit , :update , :destroy , :show , :copy , :index_chosen , :close_issue , :lock_issue ]
include ApplicationHelper
def index
issues = @project . issues . includes ( :user , :tracker , :priority , :version , :issue_status , :journals )
issues = issues . where ( is_private : false ) unless current_user . present? && ( current_user . admin? || @project . member? ( current_user ) )
@all_issues_size = issues . size
@open_issues_size = issues . where . not ( status_id : 5 ) . size
@close_issues_size = issues . where ( status_id : 5 ) . size
@assign_to_me_size = issues . where ( assigned_to_id : current_user & . id ) . size
@my_published_size = issues . where ( author_id : current_user & . id ) . size
status_type = params [ :status_type ] . to_s #issue状态的选择
search_name = params [ :search ] . to_s
start_time = params [ :start_date ]
end_time = params [ :due_date ]
if status_type . to_s == " 1 " #表示开启中的
issues = issues . where . not ( status_id : 5 )
elsif status_type . to_s == " 2 " #表示关闭中的
issues = issues . where ( status_id : 5 )
end
if search_name . present?
issues = issues . where ( " subject like ? " , " % #{ search_name } % " )
end
if start_time & . present? || end_time & . present?
issues = issues . where ( " start_date between ? and ? " , start_time & . present? ? start_time . to_date : Time . now . to_date , end_time & . present? ? end_time . to_date : Time . now . to_date )
end
issues = issues . where ( author_id : params [ :author_id ] ) if params [ :author_id ] . present?
issues = issues . where ( assigned_to_id : params [ :assigned_to_id ] ) if params [ :assigned_to_id ] . present?
issues = issues . where ( tracker_id : params [ :tracker_id ] ) if params [ :tracker_id ] . present?
issues = issues . where ( status_id : params [ :status_id ] ) if params [ :status_id ] . present?
issues = issues . where ( priority_id : params [ :priority_id ] ) if params [ :priority_id ] . present?
issues = issues . where ( fixed_version_id : params [ :fixed_version_id ] ) if params [ :fixed_version_id ] . present?
issues = issues . where ( done_ratio : params [ :done_ratio ] . to_i ) if params [ :done_ratio ] . present?
issues = issues . where ( issue_type : params [ :issue_type ] ) if params [ :issue_type ] . present?
issues = issues . joins ( :issue_tags ) . where ( issue_tags : { id : params [ :issue_tag_id ] . to_i } ) if params [ :issue_tag_id ] . present?
order_type = params [ :order_type ] || " desc " #或者"asc"
order_name = params [ :order_name ] || " created_on " #或者"updated_on"
@page = params [ :page ]
@limit = params [ :limit ] || 15
@issues = issues . order ( " #{ order_name } #{ order_type } " )
@issues_size = issues . size
@issues = issues . order ( " #{ order_name } #{ order_type } " ) . page ( @page ) . per ( @limit )
respond_to do | format |
format . json
format . xlsx {
set_export_cookies
export_issues ( @issues )
export_name = " #{ @project . name } _issues列表_ #{ Time . now . strftime ( '%Y%m%d_%H%M%S' ) } "
render xlsx : " #{ export_name . strip } " , template : " issues/index.xlsx.axlsx " , locals : { table_columns : @table_columns , issues : @export_issues }
}
end
end
def index_chosen
@issue_chosen = issue_left_chosen ( @project , nil )
end
def commit_issues
issues = @project . issues . includes ( :user , :tracker )
issues = issues . where ( is_private : false ) unless current_user . present? && ( current_user . admin? || @project . member? ( current_user ) )
@all_issues_size = issues . size
@open_issues_size = issues . where . not ( status_id : 5 ) . size
@close_issues_size = issues . where ( status_id : 5 ) . size
@normal_issues_size = issues . where ( issue_type : " 1 " ) . size
@pay_issues_size = issues . where ( issue_type : " 2 " ) . size
status_type = params [ :status_type ] . to_s
if status_type . to_s == " 1 " #表示开启中的
issues = issues . where . not ( status_id : 5 )
elsif status_type . to_s == " 2 " #表示关闭中的
issues = issues . where ( status_id : 5 )
elsif status_type . to_s == " 3 " #普通
issues = issues . where ( issue_type : " 1 " )
elsif status_type . to_s == " 4 " #悬赏
issues = issues . where ( issue_type : " 2 " )
end
@commit_issues = [ ]
total_commit_issues = {
name : " 合计 " ,
user_login : nil ,
all_count : issues . size ,
trackers : trackers_size ( issues )
}
@commit_issues . push ( total_commit_issues )
members = issues . pluck ( :assigned_to_id ) . uniq
members . each do | m |
user = User . select ( :id , :login , :firstname , :lastname ) . find ( m )
user_issues = issues . where ( assigned_to_id : m ) #指派给
member_params = {
name : user . try ( :show_real_name ) ,
user_login : user . try ( :login ) ,
all_count : issues . size ,
trackers : trackers_size ( user_issues )
}
@commit_issues . push ( member_params )
end
un_assign = issues . where ( assigned_to_id : nil )
total_commit_issues = {
name : " 未指派 " ,
user_login : nil ,
all_count : un_assign . size ,
trackers : trackers_size ( un_assign )
}
@commit_issues . push ( total_commit_issues )
end
def new
@issue_chosen = issue_left_chosen ( @project , nil )
end
def create
if params [ :subject ] . blank?
normal_status ( - 1 , " 标题不能为空 " )
elsif params [ :subject ] . to_s . size > 255
normal_status ( - 1 , " 标题不能超过255个字符 " )
elsif ( params [ :issue_type ] . to_s == " 2 " ) && params [ :token ] . to_i == 0
normal_status ( - 1 , " 悬赏的奖金必须大于0 " )
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_type : params [ :issue_type ] ,
token : params [ :token ] ,
issue_tags_value : params [ :issue_tag_ids ] . present? ? params [ :issue_tag_ids ] . join ( " , " ) : " " ,
closed_on : ( params [ :status_id ] . to_i == 5 ) ? Time . now : nil ,
}
@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 [ :issue_tag_ids ] . present?
params [ :issue_tag_ids ] . each do | tag |
IssueTagsRelate . create! ( issue_id : @issue . id , issue_tag_id : tag )
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
@issue . project_trends . create ( user_id : current_user . id , project_id : @project . id , action_type : " create " )
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 ] ,
closed_on : ( params [ :status_id ] . to_i == 5 ) ? Time . now : nil ,
issue_type : params [ :issue_type ] ,
issue_tags_value : params [ :issue_tag_ids ] . present? ? params [ :issue_tag_ids ] . join ( " , " ) . to_s : " " ,
token : params [ :token ]
}
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
if params [ :issue_tag_ids ] . present?
issue_current_tags = @issue & . issue_tags & . select ( :id ) & . pluck ( :id )
new_tag_ids = params [ :issue_tag_ids ] - issue_current_tags
old_tag_ids = issue_current_tags - params [ :issue_tag_ids ]
if old_tag_ids . size > 0
@issue . issue_tags_relates . where ( issue_tag_id : old_tag_ids ) . delete_all
end
if new_tag_ids . size > 0
new_tag_ids . each do | tag |
IssueTagsRelate . create ( issue_id : @issue . id , issue_tag_id : tag )
end
end
end
if params [ :status_id ] . to_i == 5
@issue . issue_times . update_all ( end_time : Time . now )
end
@issue . create_journal_detail ( change_files , issue_files , issue_file_ids )
normal_status ( 0 , " 更新成功 " )
else
normal_status ( - 1 , " 更新失败 " )
end
end
def show
@user_permission = current_user . present? && ( ! @issue . is_lock || @project . member? ( current_user ) || current_user . admin? || @issue . user == current_user )
@issue_attachments = @issue . attachments
@issue_user = @issue . user
@issue_assign_to = @issue . get_assign_user
@join_users = join_users ( @issue )
#总耗时
cost_time ( @issue )
#被依赖
@be_depended_issues_array = be_depended_issues ( @issue )
#依赖于
depended_issues ( @issue )
end
def destroy
if @issue . destroy
normal_status ( 0 , " 删除成功 " )
else
normal_status ( - 1 , " 删除失败 " )
end
end
def copy
@new_issue = @issue . dup
if @new_issue . save
@status = 1
else
@status = - 1
end
end
def close_issue
type = params [ :status_id ] . to_i || 5
if type == 5
message = " 关闭 "
else
message = " 重新开启 "
end
if @issue . update_attribute ( :status_id , type )
if type == 5
@issue . project_trends . create ( user_id : current_user . id , project_id : @project . id , action_type : " close " )
@issue . issue_times . update_all ( end_time : Time . now )
end
@issue . create_journal_detail ( false , [ ] , [ ] )
normal_status ( 0 , message )
else
normal_status ( - 1 , " 操作失败 " )
end
end
def lock_issue
if @issue . user == current_user || current_user . admin?
type = ( params [ :lock_type ] . to_i == 1 )
if @issue . update_attribute ( :is_lock , type )
if type
@issue . custom_journal_detail ( " lock_issue " , " " , " 因为 #{ params [ :lock_reason ] . present? ? params [ :lock_reason ] . to_s : " 某种原因 " } 而锁定,并将对话限制为协作者 " )
else
@issue . custom_journal_detail ( " unlock_issue " , " " , " 解除锁定 " )
end
normal_status ( 0 , " 操作成功 " )
else
normal_status ( - 1 , " 操作失败 " )
end
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 ] )
if @issue . blank?
normal_status ( - 1 , " 标签不存在 " )
elsif @issue . is_lock && ! ( @project . member? ( current_user ) || current_user . admin? )
normal_status ( - 1 , " 您没有权限 " )
end
end
def check_issue_permission
unless @project . member? ( current_user ) || current_user . admin?
normal_status ( - 1 , " 您没有权限 " )
end
end
def join_users ( issue )
#协作者
issue_comment_users_array = [ ]
issue_comment_users = issue . journals . select ( :user_id ) . distinct
if issue . present? && issue_comment_users . size > 0
issue_comment_users . each do | j |
user_avatar = url_to_avatar ( j . user )
issue_comment_users_array . push ( { login : j . user . try ( :login ) , avatar_url : user_avatar } )
end
end
issue_comment_users_array
end
def cost_time ( issue )
#总耗时
@cost_time_array = [ ]
@all_cost_time = 0
all_issue_times = issue . issue_times . includes ( :user ) . where . not ( end_time : nil )
if issue . present? && all_issue_times . size > 0
all_issue_times . each do | time |
cost_time = time . end_time . to_i - time . start_time . to_i
cost_time = cost_time > 0 ? cost_time : 0
@all_cost_time = @all_cost_time + cost_time
set_cost_time = Time . at ( cost_time ) . utc . strftime ( '%H h %M min %S s' )
@cost_time_array . push ( { login : time . user . try ( :login ) , avatar_url : url_to_avatar ( time . user ) , cost_time : set_cost_time } )
end
end
end
def depended_issues ( issue )
#依赖于
@depended_issues_id = [ ]
@depended_issues_array = [ ]
depended_issues = issue . issue_depends . pluck ( :id , :depend_issue_id ) . uniq
if issue . present? && depended_issues . size > 0
depended_issues . each do | de |
@depended_issues_id . push ( de [ 1 ] )
issues = Issue . select ( :id , :subject ) . where ( id : de [ 1 ] ) . as_json
issues = issues . first . merge ( depend_id : de [ 0 ] )
@depended_issues_array . push ( issues )
end
@depended_issues_id . delete ( issue . id )
end
end
def be_depended_issues ( issue )
be_depended_issues_array = [ ]
be_depended_issues = IssueDepend . where ( depend_issue_id : issue . id ) . pluck ( :id , :issue_id ) . uniq
if issue . present? && be_depended_issues . size > 0
be_depended_issues . each do | de |
d_issues = Issue . select ( :id , :subject ) . where ( id : de [ 1 ] ) . as_json
d_issues = d_issues . first . merge ( depend_id : de [ 0 ] )
be_depended_issues_array . push ( d_issues )
end
end
be_depended_issues_array
end
def issue_left_chosen ( project , issue_id )
issue_info = Array . new ( 11 )
use_tags = [ ]
issue_comment_users_array = [ ]
cost_time_array = [ ]
all_cost_time = 0
be_depended_issues_array = [ ]
depended_issues_array = [ ]
all_issues = [ ]
depended_issues_id = [ ]
if issue_id . present?
issue = Issue . find ( issue_id )
use_tags = issue . issue_tags . select ( :id ) . pluck ( :id )
select_arrays = [ :assigned_to_id , :tracker_id , :status_id , :priority_id , :fixed_version_id , :start_date , :due_date , :estimated_hours , :done_ratio , :issue_type , :token ]
issue_info = Issue . select ( select_arrays ) . where ( id : issue_id ) . pluck ( select_arrays )
issue_info = issue_info [ 0 ]
issue_comment_users_array = join_users ( issue )
#总耗时
cost_time ( issue )
cost_time_array = @cost_time_array
all_cost_time = @all_cost_time
#被依赖
be_depended_issues_array = be_depended_issues ( issue )
#依赖于
depended_issues ( issue )
depended_issues_array = @depended_issues_array
depended_issues_id = @depended_issues_id
end
project_members = project . members_user_infos
project_members_info = [ ] #指派给
project_members . each do | member |
user = member . user
real_name = user . try ( :show_real_name )
user_id = member [ 0 ]
is_chosen = ( ( user . id . to_s == issue_info [ 0 ] . to_s ) ? " 1 " : " 0 " )
member_info = { id : user_id , name : real_name , avatar_url : url_to_avatar ( user ) , 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 = IssuePriority & . pluck ( :id , :name , :position )
new_priority_info = [ ] #优先度
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 ] , position : 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 = { id :t . to_i , ratio : ( t . to_s + " % " ) , is_chosen : is_chosen }
new_done_info . push ( new_issue )
end
end
issue_tags = project . issue_tags & . pluck ( :id , :name , :color )
new_tags_info = [ ] #issue标签
if issue_tags . size > 0
issue_tags . each do | t |
is_chosen = ( use_tags . size > 0 && use_tags . include? ( t [ 0 ] ) ) ? " 1 " : " 0 "
new_issue = { id : t [ 0 ] , name : t [ 1 ] , color : t [ 2 ] , is_chosen : is_chosen }
new_tags_info . push ( new_issue )
end
end
issue_types = %w( 普通 悬赏 )
new_types_info = [ ] #issue标签
issue_types . each_with_index do | i , index |
is_chosen = ( issue_info [ 9 ] == " #{ index + 1 } " ) ? " 1 " : " 0 "
is_token = ( index . to_s == " 1 " ) ? issue_info [ 10 ] : nil
new_type_info = { id : index + 1 , name : i , token : is_token , is_chosen : is_chosen }
new_types_info . push ( new_type_info )
end
depend_other_issues = project . issues . where . not ( id : issue_id ) & . pluck ( :id , :subject )
if depend_other_issues . size > 0
depend_other_issues . each do | t |
is_chosen = depended_issues_id . include? ( t [ 0 ] ) ? " 1 " : " 0 "
new_issue = { id : t [ 0 ] , subject : t [ 1 ] , is_chosen : is_chosen }
all_issues . push ( new_issue )
end
end
{
" assign_user " : project_members_info ,
" tracker " : new_tracker_info ,
" issue_status " : new_status_info ,
" priority " : new_priority_info ,
" issue_version " : new_version_info ,
" start_date " : issue_info [ 5 ] ,
" due_date " : issue_info [ 6 ] ,
" joins_users " : issue_comment_users_array ,
" cost_time_users " : cost_time_array ,
" total_cost_time " : Time . at ( all_cost_time ) . utc . strftime ( '%H h %M min %S s' ) ,
" be_depended_issues " : be_depended_issues_array ,
" depended_issues " :depended_issues_array ,
" estimated_hours " : issue_info [ 7 ] ,
" done_ratio " : new_done_info ,
" issue_tag " : new_tags_info ,
" issue_type " : new_types_info ,
" all_issues " : all_issues
}
end
def export_issues ( issues )
@table_columns = %w( ID 类型 标题 描述 状态 指派给 优先级 标签 发布人 创建时间 里程碑 开始时间 截止时间 完成度 分类 金额 )
@export_issues = [ ]
issues . each do | i |
issue_array = [ i . id , i . tracker . try ( :name ) , i . subject , i . description , i . issue_status . try ( :name ) , i . get_assign_user . try ( :show_real_name ) ,
i . priority . try ( :name ) , i . get_issue_tags_name , i . user . try ( :show_real_name ) , format_time ( i . created_on ) , i . version . try ( :title ) ,
i . start_date . to_s , i . due_date . to_s , i . done_ratio . to_s + " % " , i . issue_type == " 2 " ? " 悬赏 " : " 普通 " , i . token . to_s ]
@export_issues . push ( issue_array )
end
end
def trackers_size ( issues )
trackers_id = Tracker . pluck ( :id , :name )
tracker_array = [ ]
trackers_id . each do | t |
tracker_info = {
id : t [ 0 ] ,
name : t [ 1 ] ,
issues_count : issues . issues_count ( t [ 0 ] )
}
tracker_array . push ( tracker_info )
end
tracker_array
end
end