diff --git a/module/product/control.php b/module/product/control.php index 6d57121b53..ef908ccc72 100755 --- a/module/product/control.php +++ b/module/product/control.php @@ -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); diff --git a/module/product/ui/track.html.php b/module/product/ui/track.html.php index e25390087b..c1710990a8 100644 --- a/module/product/ui/track.html.php +++ b/module/product/ui/track.html.php @@ -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']) diff --git a/module/story/model.php b/module/story/model.php index 3bcc7025d6..6dd2841a0c 100644 --- a/module/story/model.php +++ b/module/story/model.php @@ -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; diff --git a/module/story/tao.php b/module/story/tao.php index 1dd4793e3d..24908dd7e2 100644 --- a/module/story/tao.php +++ b/module/story/tao.php @@ -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; diff --git a/module/story/test/model/gettracks.php b/module/story/test/model/gettracks.php deleted file mode 100755 index be15d33fff..0000000000 --- a/module/story/test/model/gettracks.php +++ /dev/null @@ -1,88 +0,0 @@ -#!/usr/bin/env php -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'); diff --git a/module/story/test/tao/getlastnodes.php b/module/story/test/tao/getlastnodes.php old mode 100644 new mode 100755 index e39ba62f82..063203709e --- a/module/story/test/tao/getlastnodes.php +++ b/module/story/test/tao/getlastnodes.php @@ -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'); \ No newline at end of file