diff --git a/apistructs/issue.go b/apistructs/issue.go index c74670a270c..e3e3135f923 100644 --- a/apistructs/issue.go +++ b/apistructs/issue.go @@ -1167,14 +1167,17 @@ type IssuesStageRequest struct { // IssueManHourSumResponse 事件下所有的任务总和响应 type IssueManHourSumResponse struct { // Header - DesignManHour int64 `json:"designManHour"` - DevManHour int64 `json:"devManHour"` - TestManHour int64 `json:"testManHour"` - ImplementManHour int64 `json:"implementManHour"` - DeployManHour int64 `json:"deployManHour"` - OperatorManHour int64 `json:"operatorManHour"` - SumElapsedTime int64 `json:"sumElapsedTime"` - SumEstimateTime int64 `json:"sumEstimateTime"` + DesignManHour int64 `json:"designManHour"` + DevManHour int64 `json:"devManHour"` + TestManHour int64 `json:"testManHour"` + ImplementManHour int64 `json:"implementManHour"` + DeployManHour int64 `json:"deployManHour"` + OperatorManHour int64 `json:"operatorManHour"` + SumElapsedTime int64 `json:"sumElapsedTime"` + SumEstimateTime int64 `json:"sumEstimateTime"` + EstimateManDayGtOneDayNum int64 `json:"estimateManDayGtOneDayNum"` + EstimateManDayGtTwoDayNum int64 `json:"estimateManDayGtTwoDayNum"` + EstimateManDayGtThreeDayNum int64 `json:"estimateManDayGtThreeDayNum"` } // IssueBugPercentageResponse 缺陷率响应 diff --git a/internal/apps/dop/providers/issue/dao/core.go b/internal/apps/dop/providers/issue/dao/core.go index a591ad6e5bf..e4ff5156ce2 100644 --- a/internal/apps/dop/providers/issue/dao/core.go +++ b/internal/apps/dop/providers/issue/dao/core.go @@ -30,6 +30,11 @@ import ( "github.com/erda-project/erda/pkg/strutil" ) +const ( + // day = 8 * 60(minute) + day = 480 +) + // Issue . type Issue struct { dbengine.BaseModel @@ -531,10 +536,13 @@ func (client *DBClient) IssueStateCount2(issueIDs []uint64) ([]apistructs.Requir // GetTaskIssueManHourSum get task mam hour sum func (client *DBClient) GetTaskIssueManHourSum(req apistructs.IssuesStageRequest) (apistructs.IssueManHourSumResponse, error) { var ( - issues []Issue - ans = make(map[string]int64) - sumElapsedTime int64 = 0 - sumEstimateTime int64 = 0 + issues []Issue + ans = make(map[string]int64) + sumElapsedTime int64 = 0 + sumEstimateTime int64 = 0 + estimateDayGtOne int64 = 0 + esitmateDayGtTwo int64 = 0 + esitmateDayGtThree int64 = 0 ) sql := client.Table("dice_issues") if len(req.StatisticRange) > 0 { @@ -565,16 +573,29 @@ func (client *DBClient) GetTaskIssueManHourSum(req apistructs.IssuesStageRequest ans[each.Stage] += ret.ElapsedTime sumElapsedTime += ret.ElapsedTime sumEstimateTime += ret.EstimateTime + estimateDay := float64(ret.EstimateTime) / day + if estimateDay > 1 { + estimateDayGtOne++ + } + if estimateDay > 2 { + esitmateDayGtTwo++ + } + if estimateDay > 3 { + esitmateDayGtThree++ + } } return apistructs.IssueManHourSumResponse{ - DesignManHour: ans["design"], - DevManHour: ans["dev"], - TestManHour: ans["test"], - ImplementManHour: ans["implement"], - DeployManHour: ans["deploy"], - OperatorManHour: ans["operator"], - SumElapsedTime: sumElapsedTime, - SumEstimateTime: sumEstimateTime, + DesignManHour: ans["design"], + DevManHour: ans["dev"], + TestManHour: ans["test"], + ImplementManHour: ans["implement"], + DeployManHour: ans["deploy"], + OperatorManHour: ans["operator"], + SumElapsedTime: sumElapsedTime, + SumEstimateTime: sumEstimateTime, + EstimateManDayGtOneDayNum: estimateDayGtOne, + EstimateManDayGtTwoDayNum: esitmateDayGtTwo, + EstimateManDayGtThreeDayNum: esitmateDayGtThree, }, nil } diff --git a/internal/apps/dop/providers/project_report/calculate.go b/internal/apps/dop/providers/project_report/calculate.go index 20ec9a5e5b1..65fc3af4332 100644 --- a/internal/apps/dop/providers/project_report/calculate.go +++ b/internal/apps/dop/providers/project_report/calculate.go @@ -23,6 +23,7 @@ import ( orgpb "github.com/erda-project/erda-proto-go/core/org/pb" "github.com/erda-project/erda/apistructs" "github.com/erda-project/erda/internal/apps/dop/dao" + "github.com/erda-project/erda/internal/apps/dop/providers/issue/core/query/issueexcel" ) func (p *provider) refreshBasicIterations() error { @@ -166,6 +167,12 @@ func (p *provider) calIterationFields(iter *IterationInfo) (*IterationMetricFiel doneReqStateIDs = append(doneReqStateIDs, int64(doneReqStates[i].ID)) } + manHour, err := issueexcel.NewManhour(iter.Iteration.ManHour) + if err != nil { + return nil, err + } + fields.IterationEstimatedDayTotal = float64(manHour.EstimateTime) / 480 + var doneTaskStateIDs []int64 doneTaskStates, err := p.issueDB.GetIssuesStatesByTypes(&apistructs.IssueStatesRequest{ ProjectID: iter.Iteration.ProjectID, @@ -259,6 +266,9 @@ func (p *provider) calIterationFields(iter *IterationInfo) (*IterationMetricFiel return nil, err } fields.TaskEstimatedMinute = uint64(totalTaskEstimateTime.SumEstimateTime) + fields.TaskEstimatedDayGtOneTotal = uint64(totalTaskEstimateTime.EstimateManDayGtOneDayNum) + fields.TaskEstimatedDayGtTwoTotal = uint64(totalTaskEstimateTime.EstimateManDayGtTwoDayNum) + fields.TaskEstimatedDayGtThreeTotal = uint64(totalTaskEstimateTime.EstimateManDayGtThreeDayNum) if fields.RequirementTotal > 0 { fields.RequirementCompleteSchedule = float64(iterationSummary.Requirement.Done) / float64(fields.RequirementTotal) diff --git a/internal/apps/dop/providers/project_report/metrics.go b/internal/apps/dop/providers/project_report/metrics.go index f1f98a37a47..225c797b72e 100644 --- a/internal/apps/dop/providers/project_report/metrics.go +++ b/internal/apps/dop/providers/project_report/metrics.go @@ -66,6 +66,9 @@ type IterationMetricFields struct { TaskUnAssociatedTotal uint64 TaskAssociatedPercent float64 TaskWorkingTotal uint64 + TaskEstimatedDayGtOneTotal uint64 + TaskEstimatedDayGtTwoTotal uint64 + TaskEstimatedDayGtThreeTotal uint64 // requirement-related metrics RequirementTotal uint64 @@ -89,8 +92,9 @@ type IterationMetricFields struct { BugWithWonfixTotal uint64 // iteration-related metrics - IterationAssigneeNum uint64 - ProjectAssigneeNum uint64 + IterationAssigneeNum uint64 + IterationEstimatedDayTotal float64 + ProjectAssigneeNum uint64 } // IsValid returns true if the IterationMetricFields is valid. @@ -237,6 +241,57 @@ var ( } }, }, + { + name: "iteration_task_estimated_day_gt_one_total", + help: "Cumulative estimated day greater than one of task type issue in iteration.", + valueType: prometheus.CounterValue, + getValues: func(iterationInfo *IterationInfo) metricValues { + var value float64 + if iterationInfo.IterationMetricFields != nil { + value = float64(iterationInfo.IterationMetricFields.TaskEstimatedDayGtOneTotal) + } + return metricValues{ + { + value: value, + timestamp: time.Now(), + }, + } + }, + }, + { + name: "iteration_task_estimated_day_gt_two_total", + help: "Cumulative estimated day greater than two of task type issue in iteration.", + valueType: prometheus.CounterValue, + getValues: func(iterationInfo *IterationInfo) metricValues { + var value float64 + if iterationInfo.IterationMetricFields != nil { + value = float64(iterationInfo.IterationMetricFields.TaskEstimatedDayGtTwoTotal) + } + return metricValues{ + { + value: value, + timestamp: time.Now(), + }, + } + }, + }, + { + name: "iteration_task_estimated_day_gt_three_total", + help: "Cumulative estimated day greater than three of task type issue in iteration.", + valueType: prometheus.CounterValue, + getValues: func(iterationInfo *IterationInfo) metricValues { + var value float64 + if iterationInfo.IterationMetricFields != nil { + value = float64(iterationInfo.IterationMetricFields.TaskEstimatedDayGtThreeTotal) + } + return metricValues{ + { + value: value, + timestamp: time.Now(), + }, + } + }, + }, { name: "iteration_task_associated_percent", help: "Accumulate the proportion of the number of requirements associated with the current task", @@ -577,6 +632,23 @@ var ( } }, }, + { + name: "iteration_estimated_day_total", + help: "The total number estimated days of the iteration", + valueType: prometheus.CounterValue, + getValues: func(iterationInfo *IterationInfo) metricValues { + var value float64 + if iterationInfo.IterationMetricFields != nil { + value = iterationInfo.IterationMetricFields.IterationEstimatedDayTotal + } + return metricValues{ + { + value: value, + timestamp: time.Now(), + }, + } + }, + }, } ) diff --git a/internal/apps/dop/providers/project_report/query.go b/internal/apps/dop/providers/project_report/query.go index 5769d69e72d..01896e8515d 100644 --- a/internal/apps/dop/providers/project_report/query.go +++ b/internal/apps/dop/providers/project_report/query.go @@ -37,46 +37,50 @@ var ( ) type ProjectReportRow struct { - RequirementTotal float64 `json:"requirementTotal" ch:"requirementTotal"` - BugTotal float64 `json:"bugTotal" ch:"bugTotal"` - TaskTotal float64 `json:"taskTotal" ch:"taskTotal"` - BudgetMandayTotal float64 `json:"budgetMandayTotal" ch:"budgetMandayTotal"` - TaskEstimatedMinute float64 `json:"taskEstimatedMinute" ch:"taskEstimatedMinute"` - TaskEstimatedManday float64 `json:"taskEstimatedManday" ch:"taskEstimatedManday"` - ActualMandayTotal float64 `json:"actualMandayTotal" ch:"actualMandayTotal"` - RequirementDoneRate float64 `json:"requirementDoneRate" ch:"requirementDoneRate"` - TaskDoneTotal float64 `json:"taskDoneTotal" ch:"taskDoneTotal"` - TaskDoneRate float64 `json:"taskDoneRate" ch:"taskDoneRate"` - UnfinishedAssigneeTotal float64 `json:"unfinishedAssigneeTotal" ch:"unfinishedAssigneeTotal"` - RequirementDoneTotal float64 `json:"requirementDoneTotal" ch:"requirementDoneTotal"` - RequirementAssociatedTotal float64 `json:"requirementAssociatedTotal" ch:"requirementAssociatedTotal"` - RequirementAssociatedRate float64 `json:"requirementAssociatedRate" ch:"requirementAssociatedRate"` - RequirementUnassignedTotal float64 `json:"requirementUnassignedTotal" ch:"requirementUnassignedTotal"` - RequirementUnassignedRate float64 `json:"requirementUnassignedRate" ch:"requirementUnassignedRate"` - TaskUnassignedTotal float64 `json:"taskUnassignedTotal" ch:"taskUnassignedTotal"` - BugUndoneTotal float64 `json:"bugUndoneTotal" ch:"bugUndoneTotal"` - BugDoneRate float64 `json:"bugDoneRate" ch:"bugDoneRate"` - BugSeriousTotal float64 `json:"bugSeriousTotal" ch:"bugSeriousTotal"` - BugSeriousRate float64 `json:"bugSeriousRate" ch:"bugSeriousRate"` - BugDemandDesignTotal float64 `json:"bugDemandDesignTotal" ch:"bugDemandDesignTotal"` - BugDemandDesignRate float64 `json:"bugDemandDesignRate" ch:"bugDemandDesignRate"` - BugOnlineTotal float64 `json:"bugOnlineTotal" ch:"bugOnlineTotal"` - BugOnlineRate float64 `json:"bugOnlineRate" ch:"bugOnlineRate"` - BugReopenTotal float64 `json:"bugReopenTotal" ch:"bugReopenTotal"` - BugReopenRate float64 `json:"bugReopenRate" ch:"bugReopenRate"` - TaskAssociatedTotal float64 `json:"taskAssociatedTotal" ch:"taskAssociatedTotal"` - TaskAssociatedRate float64 `json:"taskAssociatedRate" ch:"taskAssociatedRate"` - BugLowLevelTotal float64 `json:"bugLowLevelTotal" ch:"bugLowLevelTotal"` - BugLowLevelRate float64 `json:"bugLowLevelRate" ch:"bugLowLevelRate"` - IterationCompletedRate float64 `json:"iterationCompletedRate" ch:"iterationCompletedRate"` - TaskWorkingTotal float64 `json:"taskWorkingTotal" ch:"taskWorkingTotal"` - BugWontfixTotal float64 `json:"bugWontfixTotal" ch:"bugWontfixTotal"` - IterationAssigneeTotal float64 `json:"iterationAssigneeTotal" ch:"iterationAssigneeTotal"` - ProjectName string `json:"projectName" ch:"projectName"` - ProjectDisplayName string `json:"projectDisplayName" ch:"projectDisplayName"` - ProjectID string `json:"projectID" ch:"projectID"` - Timestamp time.Time `json:"timestamp" ch:"timestamp"` - EmpProjectCode string `json:"empProjectCode" ch:"empProjectCode"` + RequirementTotal float64 `json:"requirementTotal" ch:"requirementTotal"` + BugTotal float64 `json:"bugTotal" ch:"bugTotal"` + TaskTotal float64 `json:"taskTotal" ch:"taskTotal"` + BudgetMandayTotal float64 `json:"budgetMandayTotal" ch:"budgetMandayTotal"` + TaskEstimatedMinute float64 `json:"taskEstimatedMinute" ch:"taskEstimatedMinute"` + TaskEstimatedManday float64 `json:"taskEstimatedManday" ch:"taskEstimatedManday"` + ActualMandayTotal float64 `json:"actualMandayTotal" ch:"actualMandayTotal"` + RequirementDoneRate float64 `json:"requirementDoneRate" ch:"requirementDoneRate"` + TaskDoneTotal float64 `json:"taskDoneTotal" ch:"taskDoneTotal"` + TaskDoneRate float64 `json:"taskDoneRate" ch:"taskDoneRate"` + TaskEstimatedDayGtOneTotal float64 `json:"taskEstimatedDayGtOneTotal" ch:"taskEstimatedDayGtOneTotal"` + TaskEstimatedDayGtTwoTotal float64 `json:"taskEstimatedDayGtTwoTotal" ch:"taskEstimatedDayGtTwoTotal"` + TaskEstimatedDayGtThreeTotal float64 `json:"taskEstimatedDayGtThreeTotal" ch:"taskEstimatedDayGtThreeTotal"` + UnfinishedAssigneeTotal float64 `json:"unfinishedAssigneeTotal" ch:"unfinishedAssigneeTotal"` + RequirementDoneTotal float64 `json:"requirementDoneTotal" ch:"requirementDoneTotal"` + RequirementAssociatedTotal float64 `json:"requirementAssociatedTotal" ch:"requirementAssociatedTotal"` + RequirementAssociatedRate float64 `json:"requirementAssociatedRate" ch:"requirementAssociatedRate"` + RequirementUnassignedTotal float64 `json:"requirementUnassignedTotal" ch:"requirementUnassignedTotal"` + RequirementUnassignedRate float64 `json:"requirementUnassignedRate" ch:"requirementUnassignedRate"` + TaskUnassignedTotal float64 `json:"taskUnassignedTotal" ch:"taskUnassignedTotal"` + BugUndoneTotal float64 `json:"bugUndoneTotal" ch:"bugUndoneTotal"` + BugDoneRate float64 `json:"bugDoneRate" ch:"bugDoneRate"` + BugSeriousTotal float64 `json:"bugSeriousTotal" ch:"bugSeriousTotal"` + BugSeriousRate float64 `json:"bugSeriousRate" ch:"bugSeriousRate"` + BugDemandDesignTotal float64 `json:"bugDemandDesignTotal" ch:"bugDemandDesignTotal"` + BugDemandDesignRate float64 `json:"bugDemandDesignRate" ch:"bugDemandDesignRate"` + BugOnlineTotal float64 `json:"bugOnlineTotal" ch:"bugOnlineTotal"` + BugOnlineRate float64 `json:"bugOnlineRate" ch:"bugOnlineRate"` + BugReopenTotal float64 `json:"bugReopenTotal" ch:"bugReopenTotal"` + BugReopenRate float64 `json:"bugReopenRate" ch:"bugReopenRate"` + TaskAssociatedTotal float64 `json:"taskAssociatedTotal" ch:"taskAssociatedTotal"` + TaskAssociatedRate float64 `json:"taskAssociatedRate" ch:"taskAssociatedRate"` + BugLowLevelTotal float64 `json:"bugLowLevelTotal" ch:"bugLowLevelTotal"` + BugLowLevelRate float64 `json:"bugLowLevelRate" ch:"bugLowLevelRate"` + IterationCompletedRate float64 `json:"iterationCompletedRate" ch:"iterationCompletedRate"` + TaskWorkingTotal float64 `json:"taskWorkingTotal" ch:"taskWorkingTotal"` + BugWontfixTotal float64 `json:"bugWontfixTotal" ch:"bugWontfixTotal"` + IterationAssigneeTotal float64 `json:"iterationAssigneeTotal" ch:"iterationAssigneeTotal"` + IterationEstimatedDayTotal float64 `json:"iterationEstimatedDayTotal" ch:"iterationEstimatedDayTotal"` + ProjectName string `json:"projectName" ch:"projectName"` + ProjectDisplayName string `json:"projectDisplayName" ch:"projectDisplayName"` + ProjectID string `json:"projectID" ch:"projectID"` + Timestamp time.Time `json:"timestamp" ch:"timestamp"` + EmpProjectCode string `json:"empProjectCode" ch:"empProjectCode"` } var ( @@ -95,6 +99,9 @@ SELECT actualMandayTotal, taskDoneTotal, taskDoneRate, + taskEstimatedDayGtOneTotal, + taskEstimatedDayGtTwoTotal, + taskEstimatedDayGtThreeTotal, requirementDoneRate, unfinishedAssigneeTotal, requirementDoneTotal, @@ -121,6 +128,7 @@ SELECT taskWorkingTotal, bugWontfixTotal, iterationAssigneeTotal, + iterationEstimatedDayTotal, projectName, projectDisplayName, projectID, @@ -138,6 +146,9 @@ FROM sum(actual_manday_total) as actualMandayTotal, sum(task_done_total) as taskDoneTotal, if(sum(task_total) > 0, sum(task_done_total) / sum(task_total), 0) as taskDoneRate, + sum(task_estimated_day_gt_one_total) as taskEstimatedDayGtOneTotal, + sum(task_estimated_day_gt_two_total) as taskEstimatedDayGtTwoTotal, + sum(task_estimated_day_gt_three_total) as taskEstimatedDayGtThreeTotal, last_value(unfinished_assignee_total) as unfinishedAssigneeTotal, sum(requirement_done_total) as requirementDoneTotal, if(sum(requirement_total) > 0, sum(requirement_done_total) / sum(requirement_total), 0) as requirementDoneRate, @@ -164,6 +175,7 @@ FROM if(sum(task_total) > 0, (4*sum(task_done_total)+sum(task_working_total))/(4*sum(task_total)), 0) as iterationCompletedRate, sum(bug_wontfix_total) as bugWontfixTotal, sum(iteration_unfinished_assignee_total) as iterationAssigneeTotal, + sum(iteration_estimated_day_total) as iterationEstimatedDayTotal, projectName, projectDisplayName, projectID, @@ -195,6 +207,9 @@ GROUP BY requirementDoneRate, taskDoneTotal, taskDoneRate, + taskEstimatedDayGtOneTotal, + taskEstimatedDayGtTwoTotal, + taskEstimatedDayGtThreeTotal, unfinishedAssigneeTotal, requirementDoneTotal, requirementAssociatedTotal, @@ -220,6 +235,7 @@ GROUP BY iterationCompletedRate, bugWontfixTotal, iterationAssigneeTotal, + iterationEstimatedDayTotal, projectName, projectDisplayName, projectID, @@ -244,6 +260,9 @@ ORDER BY last_value(actual_manday_total) as actual_manday_total, last_value(task_done_total) as task_done_total, last_value(task_working_total) as task_working_total, + last_value(task_estimated_day_gt_one_total) as task_estimated_day_gt_one_total, + last_value(task_estimated_day_gt_two_total) as task_estimated_day_gt_two_total, + last_value(task_estimated_day_gt_three_total) as task_estimated_day_gt_three_total, last_value(unfinished_assignee_total) as unfinished_assignee_total, last_value(requirement_done_total) as requirement_done_total, last_value(requirement_associated_total) as requirement_associated_total, @@ -257,7 +276,8 @@ ORDER BY last_value(task_associated_total) as task_associated_total, last_value(bug_low_level_total) as bug_low_level_total, last_value(bug_wontfix_total) as bug_wontfix_total, - last_value(iteration_unfinished_assignee_total) as iteration_unfinished_assignee_total + last_value(iteration_unfinished_assignee_total) as iteration_unfinished_assignee_total, + last_value(iteration_estimated_day_total) as iteration_estimated_day_total FROM ( %s ) @@ -284,6 +304,9 @@ ORDER BY number_field_values[indexOf(number_field_keys,'emp_project_actual_manday_total')] as actual_manday_total, number_field_values[indexOf(number_field_keys,'iteration_task_done_total')] as task_done_total, number_field_values[indexOf(number_field_keys,'iteration_task_working_total')] as task_working_total, + number_field_values[indexOf(number_field_keys,'iteration_task_estimated_day_gt_one_total')] as task_estimated_day_gt_one_total, + number_field_values[indexOf(number_field_keys,'iteration_task_estimated_day_gt_two_total')] as task_estimated_day_gt_two_total, + number_field_values[indexOf(number_field_keys,'iteration_task_estimated_day_gt_three_total')] as task_estimated_day_gt_three_total, number_field_values[indexOf(number_field_keys,'project_assignee_total')] as unfinished_assignee_total, number_field_values[indexOf(number_field_keys,'iteration_requirement_done_total')] as requirement_done_total, number_field_values[indexOf(number_field_keys,'iteration_requirement_associated_task_total')] as requirement_associated_total, @@ -297,7 +320,8 @@ ORDER BY number_field_values[indexOf(number_field_keys,'iteration_task_inclusion_requirement_total')] as task_associated_total, number_field_values[indexOf(number_field_keys,'low_level_bug_total')] as bug_low_level_total, number_field_values[indexOf(number_field_keys,'iteration_bug_wontfix_total')] as bug_wontfix_total, - number_field_values[indexOf(number_field_keys,'iteration_assignee_total')] as iteration_unfinished_assignee_total + number_field_values[indexOf(number_field_keys,'iteration_assignee_total')] as iteration_unfinished_assignee_total, + number_field_values[indexOf(number_field_keys,'iteration_estimated_day_total')] as iteration_estimated_day_total FROM monitor.external_metrics_all WHERE metric_group='%s'