+ Add consumed and teamCount of projects for performance optimization.

This commit is contained in:
zhujinyong
2023-05-12 09:31:20 +08:00
parent 94b818161c
commit d5560c2d35
7 changed files with 28 additions and 80 deletions
+2 -1
View File
@@ -2,4 +2,5 @@ ALTER TABLE `zt_project`
ADD `progress` decimal(5,2) NOT NULL DEFAULT '0' AFTER `realDuration`,
ADD `estimate` float NOT NULL DEFAULT '0' AFTER `progress`,
ADD `left` float NOT NULL DEFAULT '0' AFTER `estimate`,
ADD `consumed` float NOT NULL DEFAULT '0' AFTER `left`;
ADD `consumed` float NOT NULL DEFAULT '0' AFTER `left`,
ADD `teamCount` int NOT NULL DEFAULT '0' AFTER `consumed`;
+2 -2
View File
@@ -364,7 +364,7 @@ class block extends control
$this->app->loadClass('pager', $static = true);
$pager = new pager(0, 30, 1);
$this->view->actions = $this->loadModel('action')->getDynamic('all', 'today', 'date_desc', $pager);
$this->view->actions = $this->loadModel('action')->getDynamic('all', 'today', 'id_desc', $pager);
$this->view->users = $this->loadModel('user')->getPairs('nodeleted|noletter|all');
$this->display();
@@ -1542,7 +1542,7 @@ class block extends control
$this->app->loadClass('pager', $static = true);
$pager = new pager(0, 30, 1);
$this->view->actions = $this->loadModel('action')->getDynamic('all', 'all', 'date_desc', $pager, 'all', $projectID);
$this->view->actions = $this->loadModel('action')->getDynamic('all', 'all', 'id_desc', $pager, 'all', $projectID);
$this->view->users = $this->loadModel('user')->getPairs('noletter');
}
-1
View File
@@ -3060,7 +3060,6 @@ class bugModel extends model
$bugs = $this->dao->select("*, IF(`pri` = 0, {$this->config->maxPriValue}, `pri`) as priOrder, IF(`severity` = 0, {$this->config->maxPriValue}, `severity`) as severityOrder")->from(TABLE_BUG)->where($bugQuery)
->beginIF(!$this->app->user->admin)->andWhere('execution')->in('0,' . $this->app->user->view->sprints)->fi()
->beginIF($excludeBugs)->andWhere('id')->notIN($excludeBugs)->fi()
->beginIF($projectID)
->andWhere('project', true)->eq($projectID)
->orWhere('project')->eq(0)
-48
View File
@@ -1369,50 +1369,6 @@ class productModel extends model
$projectKeys = array_keys($projects);
$stats = array();
$hours = array();
$emptyHour = array('totalEstimate' => 0, 'totalConsumed' => 0, 'totalLeft' => 0, 'progress' => 0);
/* Get all tasks and compute totalEstimate, totalConsumed, totalLeft, progress according to them. */
$tasks = $this->dao->select('id, project, estimate, consumed, `left`, status, closedReason')
->from(TABLE_TASK)
->where('project')->in($projectKeys)
->andWhere('parent')->lt(1)
->andWhere('deleted')->eq(0)
->fetchGroup('project', 'id');
/* Compute totalEstimate, totalConsumed, totalLeft. */
foreach($tasks as $projectID => $projectTasks)
{
$hour = (object)$emptyHour;
foreach($projectTasks as $task)
{
if($task->status != 'cancel')
{
$hour->totalEstimate += $task->estimate;
$hour->totalConsumed += $task->consumed;
}
if($task->status != 'cancel' and $task->status != 'closed') $hour->totalLeft += $task->left;
}
$hours[$projectID] = $hour;
}
/* Compute totalReal and progress. */
$progressList = $this->loadModel('project')->getWaterfallProgress(array_keys($hours));
foreach($hours as $projectID => $hour)
{
$hour->totalEstimate = round($hour->totalEstimate, 1) ;
$hour->totalConsumed = round($hour->totalConsumed, 1);
$hour->totalLeft = round($hour->totalLeft, 1);
$hour->totalReal = $hour->totalConsumed + $hour->totalLeft;
$hour->progress = $projects[$projectID]->model == 'waterfall' ? $progressList[$projectID] : ($hour->totalReal ? round($hour->totalConsumed / $hour->totalReal, 2) * 100 : 0);
}
/* Get the number of project teams. */
$teams = $this->dao->select('root,count(*) as teams')->from(TABLE_TEAM)
->where('root')->in($projectKeys)
->andWhere('type')->eq('project')
->groupBy('root')
->fetchAll('root');
/* Process projects. */
foreach($projects as $key => $project)
@@ -1426,10 +1382,6 @@ class productModel extends model
if($delay > 0) $project->delay = $delay;
}
/* Process the hours. */
$project->hours = isset($hours[$project->id]) ? $hours[$project->id] : (object)$emptyHour;
$project->teamCount = isset($teams[$project->id]) ? $teams[$project->id]->teams : 0;
$stats[] = $project;
}
return $stats;
+4 -4
View File
@@ -92,11 +92,11 @@
<td title='<?php echo $budgetTitle;?>' class="text-ellipsis text-right"><?php echo $budgetTitle;?></td>
<td class='padding-right text-left'><?php echo $project->begin;?></td>
<td class='padding-right text-left'><?php echo $project->end;?></td>
<td class="text-right" title="<?php echo $project->hours->totalEstimate . ' ' . $lang->execution->workHour;?>"><?php echo $project->hours->totalEstimate . $lang->execution->workHourUnit;?></td>
<td class="text-right" title="<?php echo $project->hours->totalConsumed . ' ' . $lang->execution->workHour;?>"><?php echo $project->hours->totalConsumed . $lang->execution->workHourUnit;?></td>
<td class="text-right" title="<?php echo $project->estimate . ' ' . $lang->execution->workHour;?>"><?php echo $project->estimate . $lang->execution->workHourUnit;?></td>
<td class="text-right" title="<?php echo $project->consumed . ' ' . $lang->execution->workHour;?>"><?php echo $project->consumed . $lang->execution->workHourUnit;?></td>
<td>
<div class='progress-pie' data-doughnut-size='90' data-color='#3CB371' data-value='<?php echo round($project->hours->progress);?>' data-width='24' data-height='24' data-back-color='#e8edf3'>
<div class='progress-info'><?php echo round($project->hours->progress);?></div>
<div class='progress-pie' data-doughnut-size='90' data-color='#3CB371' data-value='<?php echo round($project->progress);?>' data-width='24' data-height='24' data-back-color='#e8edf3'>
<div class='progress-info'><?php echo round($project->progress);?></div>
</div>
</td>
</tr>
+19 -4
View File
@@ -1370,13 +1370,21 @@ class programModel extends model
if(empty($projects)) return;
}
/* 1. Get executions to be refreshed. */
/* 1. Get summary and members of executions to be refreshed. */
$summary = $this->dao->select('execution, SUM(estimate) AS totalEstimate, SUM(consumed) AS totalConsumed, SUM(`left`) AS totalLeft')->from(TABLE_TASK)
->where('deleted')->eq(0)
->beginIF(!empty($projects))->andWhere('project')->in($projects)->fi()
->groupBy('execution')
->fetchAll();
if(empty($summary)) return;
$teamMembers = $this->dao->select('t1.root, COUNT(1) AS members')->from(TABLE_TEAM)->alias('t1')
->leftJoin(TABLE_USER)->alias('t2')->on('t1.account=t2.account')
->where('t1.type')->eq('project')
->beginIF(!empty($projects))->andWhere('t1.root')->in($projects)->fi()
->andWhere('t2.deleted')->eq(0)
->groupBy('t1.root')
->fetchPairs('root');
/* 2. Get all parents to be refreshed. */
$executions = array();
@@ -1392,13 +1400,19 @@ class programModel extends model
$executionID = $execution->execution;
foreach($executionPaths[$executionID] as $nodeID)
{
if(!isset($stats[$nodeID])) $stats[$nodeID] = array('totalEstimate' => 0, 'totalConsumed' => 0, 'totalLeft' => 0);
if(!isset($stats[$nodeID])) $stats[$nodeID] = array('totalEstimate' => 0, 'totalConsumed' => 0, 'totalLeft' => 0, 'teamCount' => 0);
$stats[$nodeID]['totalEstimate'] += $execution->totalEstimate;
$stats[$nodeID]['totalConsumed'] += $execution->totalConsumed;
$stats[$nodeID]['totalLeft'] += $execution->totalLeft;
}
}
foreach($teamMembers as $projectID => $teamCount)
{
if(!isset($stats[$projectID])) $stats[$projectID] = array('totalEstimate' => 0, 'totalConsumed' => 0, 'totalLeft' => 0, 'teamCount' => 0);
$stats[$projectID]['teamCount'] = $teamCount;
}
/* 4. Refresh stats to db. */
foreach($stats as $projectID => $project)
{
@@ -1406,6 +1420,7 @@ class programModel extends model
$progress = $totalReal ? round($project['totalConsumed'] / $totalReal, 2) * 100 : 0;
$this->dao->update(TABLE_PROJECT)
->set('progress')->eq($progress)
->set('teamCount')->eq($project['teamCount'])
->set('estimate')->eq($project['totalEstimate'])
->set('consumed')->eq($project['totalConsumed'])
->set('left')->eq($project['totalLeft'])
@@ -1461,7 +1476,6 @@ class programModel extends model
if($delay > 0) $project->delay = $delay;
}
$project->teamCount = isset($teamMembers[$project->id]) ? count($teamMembers[$project->id]) : 0;
$project->teamMembers = isset($teamMembers[$project->id]) ? array_keys($teamMembers[$project->id]) : array();
/* Convert predefined HTML entities to characters. */
@@ -1469,6 +1483,7 @@ class programModel extends model
$stats[$key] = $project;
}
return $stats;
}
+1 -20
View File
@@ -297,7 +297,7 @@ class projectModel extends model
* @access public
* @return array
*/
public function getOverviewList($queryType = 'byStatus', $param = 'all', $orderBy = 'id_desc', $limit = 15, $excludedModel = '')
public function getOverviewList($queryType = 'byStatus', $param = 'all', $orderBy = 'id_desc', $limit = 10, $excludedModel = '')
{
$queryType = strtolower($queryType);
$projects = $this->dao->select('*')->from(TABLE_PROJECT)
@@ -316,31 +316,12 @@ class projectModel extends model
if(empty($projects)) return array();
$projectIdList = array_keys($projects);
$teams = $this->dao->select('t1.root, count(t1.id) as teams')->from(TABLE_TEAM)->alias('t1')
->leftJoin(TABLE_USER)->alias('t2')->on('t1.account=t2.account')
->where('t1.root')->in($projectIdList)
->andWhere('t1.type')->eq('project')
->andWhere('t2.deleted')->eq(0)
->groupBy('root')->fetchPairs();
$hours = $this->dao->select('t2.project, ROUND(SUM(t1.consumed), 1) AS consumed, ROUND(SUM(t1.estimate), 1) AS estimate')->from(TABLE_TASK)->alias('t1')
->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.execution = t2.id')
->where('t2.project')->in($projectIdList)
->andWhere('t2.deleted')->eq(0)
->andWhere('t1.deleted')->eq(0)
->andWhere('t1.parent')->lt(1)
->groupBy('t2.project')
->fetchAll('project');
$storySummary = $this->getTotalStoriesByProject($projectIdList);
$taskSummary = $this->getTotalTaskByProject($projectIdList);
$bugSummary = $this->getTotalBugByProject($projectIdList);
foreach($projects as $projectID => $project)
{
$project->consumed = isset($hours[$projectID]) ? (float)$hours[$projectID]->consumed : 0;
$project->estimate = isset($hours[$projectID]) ? (float)$hours[$projectID]->estimate : 0;
$project->teamCount = isset($teams[$projectID]) ? $teams[$projectID] : 0;
$project->leftBugs = isset($bugSummary[$projectID]) ? $bugSummary[$projectID]->leftBugs : 0;
$project->allBugs = isset($bugSummary[$projectID]) ? $bugSummary[$projectID]->allBugs : 0;
$project->doneBugs = isset($bugSummary[$projectID]) ? $bugSummary[$projectID]->doneBugs : 0;