gs ,.
This commit is contained in:
@@ -824,7 +824,7 @@ class product extends control
|
||||
/* Load pager. */
|
||||
$this->app->loadClass('pager', true);
|
||||
$pager = new pager($recTotal, $recPerPage, $pageID);
|
||||
$stories = $this->productZen->getStories($projectID, $productID, $branch, 0, (int)$param, ($browseType == 'bysearch' ? $storyType : 'all'), $browseType, $orderBy, $pager);
|
||||
$stories = $this->productZen->getStories($projectID, $productID, $branch, 0, (int)$param, ($browseType == 'bysearch' ? $storyType : 'all'), $browseType, "type_desc,grade_desc,{$orderBy}", $pager);
|
||||
$tracks = $this->loadModel('story')->getTracksByStories($stories, $storyType);
|
||||
|
||||
$customFields = $this->productZen->getCustomFieldsForTrack($storyType);
|
||||
|
||||
@@ -28,8 +28,8 @@ foreach($lang->story->trackOrderByList as $orderByType => $orderByName)
|
||||
$item['text'] = $orderByName;
|
||||
$item['selected'] = strpos($orderBy, $orderByType) === 0;
|
||||
$item['items'] = array();
|
||||
$item['items'][] = array('text' => $lang->story->trackSortList['asc'], 'selected' => $orderBy == "{$orderByType}_asc", 'url' => createLink($app->rawModule, 'track', sprintf($paramTemplate, $storyType, "{$orderByType}_asc")));
|
||||
$item['items'][] = array('text' => $lang->story->trackSortList['desc'], 'selected' => $orderBy == "{$orderByType}_desc", 'url' => createLink($app->rawModule, 'track', sprintf($paramTemplate, $storyType, "{$orderByType}_desc")));
|
||||
$item['items'][] = array('text' => $lang->story->trackSortList['asc'], 'selected' => $orderBy == "{$orderByType}_asc", 'url' => createLink($app->rawModule, 'track', sprintf($paramTemplate, $storyType, "{$orderByType}_asc") . "&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}"));
|
||||
$item['items'][] = array('text' => $lang->story->trackSortList['desc'], 'selected' => $orderBy == "{$orderByType}_desc", 'url' => createLink($app->rawModule, 'track', sprintf($paramTemplate, $storyType, "{$orderByType}_desc") . "&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}"));
|
||||
$orderByItems[] = $item;
|
||||
|
||||
if($item['selected'])
|
||||
|
||||
+8
-62
@@ -3915,55 +3915,6 @@ class storyModel extends model
|
||||
return $forceReview;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据产品或项目,获取需求跟踪矩阵。
|
||||
* Get tracks by producr or project.
|
||||
*
|
||||
* @param int $productID
|
||||
* @param string|int $branch
|
||||
* @param int $projectID
|
||||
* @param object $pager
|
||||
* @access public
|
||||
* @return array|false
|
||||
*/
|
||||
public function getTracks(int $productID = 0, string|int $branch = 0, int $projectID = 0, object|null $pager = null): array|false
|
||||
{
|
||||
/* 获取从用户需求开始的跟踪矩阵信息。 */
|
||||
$tracks = $this->getRequirements4Track($productID, $branch, $projectID, $pager);
|
||||
if(count($tracks) >= $pager->recPerPage) return $tracks;
|
||||
|
||||
/* 如果没有用户需求,或者需求不满一页,用非细分的研发需求补充。 */
|
||||
$excludeStories = $this->storyTao->getSubdividedStoriesByProduct($productID);
|
||||
if($projectID)
|
||||
{
|
||||
$stories = $this->getExecutionStories($projectID, $productID, '`order`_desc', 'all', '0', 'story', $excludeStories, $this->config->URAndSR ? null : $pager);
|
||||
}
|
||||
else
|
||||
{
|
||||
$stories = $this->getProductStories($productID, $branch, '', 'all', 'story', 'id_desc', true, $excludeStories, $this->config->URAndSR ? null : $pager);
|
||||
}
|
||||
if(empty($stories)) return $tracks;
|
||||
|
||||
/* 展开子需求。 */
|
||||
$expandedStories = array();
|
||||
foreach($stories as $id => $story)
|
||||
{
|
||||
$expandedStories[$id] = $story;
|
||||
|
||||
if(!isset($story->children) or count($story->children) == 0) continue;
|
||||
foreach($story->children as $childID => $child) $expandedStories[$childID] = $child;
|
||||
}
|
||||
|
||||
/* 获取需求的跟踪矩阵信息。 */
|
||||
foreach($expandedStories as $id => $story) $expandedStories[$id] = $this->storyTao->buildStoryTrack($story, $projectID);
|
||||
|
||||
/* 跟踪列表中追加 noRequirement 项。如果设置了用户需求,跟踪总条目加1。 */
|
||||
$tracks['noRequirement'] = $expandedStories;
|
||||
if($this->config->URAndSR) $pager->recTotal += 1;
|
||||
|
||||
return $tracks;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据传入的需求获取跟踪矩阵,返回看板格式数据。
|
||||
* Get track by stories, return kanban format.
|
||||
@@ -3978,8 +3929,8 @@ class storyModel extends model
|
||||
if(empty($stories)) return array();
|
||||
|
||||
$rootIdList = array_unique(array_column($stories, 'root'));
|
||||
$allStories = $this->dao->select('id,parent,color,isParent,root,path,grade,product,pri,type,status,stage,title,estimate')->from(TABLE_STORY)->where('root')->in($rootIdList)->andWhere('deleted')->eq(0)->orderBy('type,grade,parent')->fetchAll('id');
|
||||
$leafNodes = $this->storyTao->getLeafNodes($stories, array_keys($allStories));
|
||||
$allStories = $this->dao->select('id,parent,color,isParent,root,path,grade,product,pri,type,status,stage,title,estimate')->from(TABLE_STORY)->where('root')->in($rootIdList)->andWhere('deleted')->eq(0)->fetchAll('id');
|
||||
$leafNodes = $this->storyTao->getLeafNodes($stories);
|
||||
|
||||
$tracks = array();
|
||||
$lanes = $this->storyTao->buildTrackLanes($leafNodes, $storyType);
|
||||
@@ -3998,7 +3949,7 @@ class storyModel extends model
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getMergeTrackCells(array $tracks, array $showCols): array
|
||||
public function getMergeTrackCells(array &$tracks, array $showCols): array
|
||||
{
|
||||
if(empty($tracks)) return array();
|
||||
|
||||
@@ -4014,10 +3965,9 @@ class storyModel extends model
|
||||
}
|
||||
}
|
||||
|
||||
$firstCol = zget(reset($storyCols), 'name', '');
|
||||
$leafNodes = $tracks['leafNodes'];
|
||||
$mergeCells = array();
|
||||
$preRoot = 0;
|
||||
$preParent = array();
|
||||
foreach($tracks['lanes'] as $lane)
|
||||
{
|
||||
$laneName = $lane['name'];
|
||||
@@ -4026,20 +3976,16 @@ class storyModel extends model
|
||||
$story = zget($leafNodes, $storyID, '');
|
||||
if(empty($story)) continue;
|
||||
|
||||
if($preRoot != $story->root)
|
||||
foreach($storyCols as $i => $col)
|
||||
{
|
||||
$preRoot = $story->root;
|
||||
continue;
|
||||
}
|
||||
if(!empty($tracks['items'][$laneName][$firstCol])) continue;
|
||||
if(!isset($preParent[$i]) || !isset($story->parent[$i]) || $preParent[$i] != $story->parent[$i]) continue;
|
||||
|
||||
foreach($storyCols as $col)
|
||||
{
|
||||
$colName = $col['name'];
|
||||
if(!empty($tracks['items'][$laneName][$colName])) break;
|
||||
if(!empty($tracks['items'][$laneName][$colName])) $tracks['items'][$laneName][$colName] = array();
|
||||
|
||||
$mergeCells[$laneName][$colName] = true;
|
||||
}
|
||||
$preParent = $story->parent;
|
||||
}
|
||||
|
||||
return $mergeCells;
|
||||
|
||||
+5
-16
@@ -2220,26 +2220,15 @@ class storyTao extends storyModel
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getLeafNodes(array $stories, array $allStoryIdList): array
|
||||
public function getLeafNodes(array $stories): array
|
||||
{
|
||||
$parent = array();
|
||||
$leafNodes = array();
|
||||
$stmt = $this->dao->select('id,parent,root,path,grade,product,pri,type,status,stage,title,estimate')->from(TABLE_STORY)->where('id')->in($allStoryIdList)->andWhere('deleted')->eq(0)->orderBy('type_desc,grade_desc,id_desc')->query();
|
||||
while($story = $stmt->fetch())
|
||||
{
|
||||
$parent[$story->parent] = true;
|
||||
|
||||
if(isset($parent[$story->id])) continue;
|
||||
$leafNodes[$story->root][$story->id] = $story;
|
||||
}
|
||||
|
||||
$sortLeafNodes = array();
|
||||
foreach($stories as $story)
|
||||
{
|
||||
if(isset($leafNodes[$story->root])) $sortLeafNodes += $leafNodes[$story->root];
|
||||
if(empty($story->isParent)) $leafNodes[$story->id] = $story;
|
||||
}
|
||||
|
||||
return $sortLeafNodes;
|
||||
return $leafNodes;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2346,9 +2335,9 @@ class storyTao extends storyModel
|
||||
foreach(explode(',', trim($node->path, ',')) as $storyID)
|
||||
{
|
||||
if(!isset($allStories[$storyID])) continue;
|
||||
$story = $allStories[$storyID];
|
||||
$story = clone $allStories[$storyID];
|
||||
|
||||
unset($allStories[$storyID]);
|
||||
//unset($allStories[$storyID]);
|
||||
if($storyType == 'requirement' && $story->type == 'epic') continue;
|
||||
if($storyType == 'story' && ($story->type == 'requirement' || $story->type == 'epic')) continue;
|
||||
if(!isset($storyGrade[$story->type][$story->grade])) continue;
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
/**
|
||||
|
||||
title=测试 storyModel->getTracks();
|
||||
cid=0
|
||||
|
||||
- 执行storyModel模块的getTracks方法,参数是0, '', 0, $pager @0
|
||||
- 执行$tracks[1]->track[11] @1
|
||||
- 执行$tracks[1]->track[11] @1
|
||||
- 执行$tracks[1]->track[11] @1
|
||||
- 执行storyModel模块的getTracks方法,参数是1, 0, 1, $pager @0
|
||||
- 执行$tracks['noRequirement'][20] @1
|
||||
- 执行$tracks['noRequirement'][11] @1
|
||||
- 执行$tracks['noRequirement'][11] @1
|
||||
|
||||
*/
|
||||
include dirname(__FILE__, 5) . '/test/lib/init.php';
|
||||
|
||||
zenData('product')->gen(2);
|
||||
$story = zenData('story');
|
||||
$story->product->range(1);
|
||||
$story->parent->range('0{18},`-1`,19');
|
||||
$story->type->range('requirement{10},story{10}');
|
||||
$story->gen(20);
|
||||
|
||||
$projectstory = zenData('projectstory');
|
||||
$projectstory->project->range(1);
|
||||
$projectstory->product->range(1);
|
||||
$projectstory->story->range('1-18');
|
||||
$projectstory->gen(18);
|
||||
|
||||
$case = zenData('case');
|
||||
$case->story->range(11);
|
||||
$case->gen(5);
|
||||
|
||||
$bug = zenData('bug');
|
||||
$bug->story->range(11);
|
||||
$bug->gen(5);
|
||||
|
||||
$task = zenData('task');
|
||||
$task->story->range('11{8},19{2}');
|
||||
$task->parent->range('0{8},`-1`,9');
|
||||
$task->gen(10);
|
||||
|
||||
$design = zenData('design');
|
||||
$design->story->range(11);
|
||||
$design->gen(10);
|
||||
|
||||
$relation = zenData('relation');
|
||||
$relation->product->range(1);
|
||||
$relation->AID->range('1,11,1,2,12,2,3,13,3,4,14,4,5,15,5,6,16,6,7,17,7,8,18,8');
|
||||
$relation->BID->range('11,1,1,12,2,2,13,3,3,14,4,4,15,5,5,16,6,6,17,7,7,18,8,8');
|
||||
$relation->AType->range('requirement,story,design');
|
||||
$relation->BType->range('story,requirement,commit');
|
||||
$relation->relation->range('subdivideinto,subdividedfrom,completedin');
|
||||
$relation->gen(24);
|
||||
|
||||
zenData('repohistory')->gen(10);
|
||||
|
||||
global $tester;
|
||||
$storyModel = $tester->loadModel('story');
|
||||
|
||||
$storyModel->config->URAndSR = 1;
|
||||
$storyModel->app->loadClass('pager', $static = true);
|
||||
$storyModel->app->moduleName = 'product';
|
||||
$storyModel->app->methodName = 'track';
|
||||
$pager = new pager(0, 20, 1);
|
||||
|
||||
r($storyModel->getTracks(0, '', 0, $pager)) && p() && e('0');
|
||||
$tracks = $storyModel->getTracks(1, '', 0, $pager);
|
||||
r(isset($tracks[1]->track[11])) && p() && e('1');
|
||||
$tracks = $storyModel->getTracks(1, '', 1, $pager);
|
||||
r(isset($tracks[1]->track[11])) && p() && e('1');
|
||||
$tracks = $storyModel->getTracks(1, 0, 1, $pager);
|
||||
r(isset($tracks[1]->track[11])) && p() && e('1');
|
||||
|
||||
$pager = new pager(0, 20, 2);
|
||||
r($storyModel->getTracks(1, 0, 1, $pager)) && p() && e('0');
|
||||
$tracks = $storyModel->getTracks(1, 0, 0, $pager);
|
||||
r(isset($tracks['noRequirement'][20])) && p() && e('1');
|
||||
|
||||
$tester->config->URAndSR = 0;
|
||||
$tracks = $storyModel->getTracks(1, '', 1, $pager);
|
||||
r(isset($tracks['noRequirement'][11])) && p() && e('1');
|
||||
$tracks = $storyModel->getTracks(1, 0, 1, $pager);
|
||||
r(isset($tracks['noRequirement'][11])) && p() && e('1');
|
||||
Regular → Executable
+6
-10
@@ -4,12 +4,11 @@
|
||||
/**
|
||||
|
||||
title=测试 storyModel->getLeafNodes();
|
||||
timeout=0
|
||||
cid=0
|
||||
|
||||
- 传入空参数。 @0
|
||||
- 只传入 allStoryIdList @0
|
||||
- 只传入 stories @0
|
||||
- 执行story模块的getLeafNodes方法,参数是$stories, $allStoryIdList @11;10;9;8;7;6;5;4
|
||||
- 执行story模块的getLeafNodes方法,参数是$stories @11;10;9;8;7;6;5;4
|
||||
|
||||
*/
|
||||
include dirname(__FILE__, 5) . '/test/lib/init.php';
|
||||
@@ -19,6 +18,7 @@ $story->product->range('1');
|
||||
$story->root->range('1{10},11');
|
||||
$story->grade->range('1,2{3},3{6},1');
|
||||
$story->parent->range('0,1{3},2{3},3{3},0');
|
||||
$story->isParent->range('1{3},0,0{3},0{3},0');
|
||||
$story->type->range('epic,requirement{3},story{6},epic');
|
||||
$story->gen(11);
|
||||
|
||||
@@ -27,11 +27,7 @@ su('admin');
|
||||
global $tester;
|
||||
$tester->loadModel('story');
|
||||
|
||||
$allStoryIdList = array(1,2,3,4,5,6,7,8,9,10,11);
|
||||
$stories = $tester->story->dao->select('*')->from(TABLE_STORY)->where('id')->in('1,11')->orderBy('id_desc')->fetchAll('id');
|
||||
$stories = $tester->story->dao->select('*')->from(TABLE_STORY)->orderBy('id_desc')->fetchAll('id');
|
||||
|
||||
r(count($tester->story->getLeafNodes(array(), array()))) && p() && e('0'); //传入空参数。
|
||||
r(count($tester->story->getLeafNodes(array(), $allStoryIdList))) && p() && e('0'); //只传入 allStoryIdList
|
||||
r(count($tester->story->getLeafNodes($stories, array()))) && p() && e('0'); //只传入 stories
|
||||
|
||||
r(implode(';', array_keys($tester->story->getLeafNodes($stories, $allStoryIdList)))) && p() && e('11;10;9;8;7;6;5;4');
|
||||
r(count($tester->story->getLeafNodes(array()))) && p() && e('0'); //传入空参数。
|
||||
r(implode(';', array_keys($tester->story->getLeafNodes($stories)))) && p() && e('11;10;9;8;7;6;5;4');
|
||||
Reference in New Issue
Block a user