diff --git a/module/product/model.php b/module/product/model.php index 17c5cff88e..35cf42f00e 100755 --- a/module/product/model.php +++ b/module/product/model.php @@ -1976,13 +1976,14 @@ class productModel extends model } /** + * 刷新产品的统计信息。 * Refresh stats info of products. * - * @param bool $refreshAll + * @param bool $refreshAll * @access public * @return void */ - public function refreshStats($refreshAll = false) + public function refreshStats(bool $refreshAll = false): void { $updateTime = zget($this->app->config->global, 'productStatsTime', ''); $now = helper::now(); @@ -1993,7 +1994,7 @@ class productModel extends model */ $productActions = array(); $products = array(); - if($updateTime < date('Y-m-d', strtotime('-14 days')) or $refreshAll) + if($updateTime < date('Y-m-d', strtotime('-14 days')) || $refreshAll) { $products = $this->dao->select('id')->from(TABLE_PRODUCT)->fetchPairs('id'); } @@ -2007,93 +2008,12 @@ class productModel extends model foreach($productActions as $productAction) { - foreach(explode(',', trim($productAction, ',')) as $product) - { - $products[$product] = $product; - } + foreach(explode(',', trim($productAction, ',')) as $product) $products[$product] = $product; } } - /* 1. Get summary and members of products to be refreshed. */ - $stories = $this->dao->select('product, status, `closedReason`, count(id) AS c') - ->from(TABLE_STORY) - ->where('deleted')->eq(0) - ->beginIF(!empty($products))->andWhere('product')->in($products)->fi() - ->andWhere('type')->eq('story') - ->groupBy('product, status, `closedReason`') - ->fetchAll(); - $productStories = array(); - foreach($stories as $story) - { - if(!isset($productStories[$story->product])) $productStories[$story->product] = array('draft' => 0, 'active' => 0, 'changing' => 0, 'reviewing' => 0, 'finished' => 0, 'closed' => 0, 'total' => 0); - if($story->status == 'draft') $productStories[$story->product]['draft'] += $story->c; - if($story->status == 'active') $productStories[$story->product]['active'] += $story->c; - if($story->status == 'changing') $productStories[$story->product]['changing'] += $story->c; - if($story->status == 'reviewing') $productStories[$story->product]['reviewing'] += $story->c; - if($story->status == 'closed') $productStories[$story->product]['closed'] += $story->c; - $productStories[$story->product]['total'] += $story->c; - - if($story->status == 'closed' && $story->closedReason == 'done') $productStories[$story->product]['finished'] += $story->c; - } - - $bugs = $this->dao->select('product,status,resolution, count(id) AS c') - ->from(TABLE_BUG) - ->where('deleted')->eq(0) - ->beginIF(!empty($products))->andWhere('product')->in($products)->fi() - ->groupBy('product, status, resolution') - ->fetchAll(); - $productBugs = array(); - foreach($bugs as $bug) - { - if(!isset($productBugs[$bug->product])) $productBugs[$bug->product] = array('unresolved' => 0, 'fixed' => 0, 'closed' => 0, 'total' => 0); - if($bug->status == 'active' || ($bug->status != 'closed' && $bug->resolution == 'postponed')) $productBugs[$bug->product]['unresolved'] += $bug->c; - - if($bug->status == 'closed' && $bug->resolution == 'fixed') $productBugs[$bug->product]['fixed'] += $bug->c; - if($bug->status == 'closed') $productBugs[$bug->product]['closed'] += $bug->c; - $productBugs[$bug->product]['total'] += $bug->c; - } - - $plans = $this->dao->select('product, count(id) AS c') - ->from(TABLE_PRODUCTPLAN) - ->where('deleted')->eq(0) - ->beginIF(!empty($products))->andWhere('product')->in($products)->fi() - ->andWhere('end')->gt(helper::now()) - ->groupBy('product') - ->fetchPairs(); - - $releases = $this->dao->select('product, count(id) AS c') - ->from(TABLE_RELEASE) - ->where('deleted')->eq(0) - ->beginIF(!empty($products))->andWhere('product')->in($products)->fi() - ->groupBy('product') - ->fetchPairs(); - - /* If products is empty, get all products. */ - if(empty($products)) $products = $this->dao->select('id')->from(TABLE_PRODUCT)->where('deleted')->eq(0)->fetchPairs(); - - $stats = array(); - foreach($products as $productID) - { - $product = new stdclass(); - - $product->draftStories = isset($productStories[$productID]) ? $productStories[$productID]['draft'] : 0; - $product->activeStories = isset($productStories[$productID]) ? $productStories[$productID]['active'] : 0; - $product->changingStories = isset($productStories[$productID]) ? $productStories[$productID]['changing'] : 0; - $product->reviewingStories = isset($productStories[$productID]) ? $productStories[$productID]['reviewing'] : 0; - $product->closedStories = isset($productStories[$productID]) ? $productStories[$productID]['closed'] : 0; - $product->finishedStories = isset($productStories[$productID]) ? $productStories[$productID]['finished'] : 0; - $product->totalStories = isset($productStories[$productID]) ? $productStories[$productID]['total'] : 0; - - $product->unresolvedBugs = isset($productBugs[$productID]) ? $productBugs[$productID]['unresolved'] : 0; - $product->closedBugs = isset($productBugs[$productID]) ? $productBugs[$productID]['closed'] : 0; - $product->fixedBugs = isset($productBugs[$productID]) ? $productBugs[$productID]['fixed'] : 0; - $product->totalBugs = isset($productBugs[$productID]) ? $productBugs[$productID]['total'] : 0; - - $product->plans = isset($plans[$productID]) ? $plans[$productID] : 0; - $product->releases = isset($releases[$productID]) ? $releases[$productID] : 0; - - $stats[$productID] = $product; - } + /* 1. Get summary of products to be refreshed. */ + $stats = $this->productTao->getProductStats($products); /* 2. Refresh stats to db. */ foreach($stats as $productID=> $product) diff --git a/module/product/tao.php b/module/product/tao.php index bd69eaaaa9..cba6e0e353 100644 --- a/module/product/tao.php +++ b/module/product/tao.php @@ -813,4 +813,128 @@ class productTao extends productModel return $data; } + + /** + * 获取产品的统计数据。 + * Get summary of products to be refreshed. + * + * @param array $productIdList + * @access protected + * @return array + */ + protected function getProductStats(array $productIdList): array + { + $productStories = $this->getStoryStats($productIdList); + $productBugs = $this->getBugStats($productIdList); + + $plans = $this->dao->select('product, count(id) AS c') + ->from(TABLE_PRODUCTPLAN) + ->where('deleted')->eq(0) + ->beginIF(!empty($productIdList))->andWhere('product')->in($productIdList)->fi() + ->andWhere('end')->gt(helper::now()) + ->groupBy('product') + ->fetchPairs(); + + $releases = $this->dao->select('product, count(id) AS c') + ->from(TABLE_RELEASE) + ->where('deleted')->eq(0) + ->beginIF(!empty($productIdList))->andWhere('product')->in($productIdList)->fi() + ->groupBy('product') + ->fetchPairs(); + + /* If products is empty, get all products. */ + if(empty($productIdList)) $productIdList = $this->dao->select('id')->from(TABLE_PRODUCT)->where('deleted')->eq(0)->fetchPairs(); + + $stats = array(); + foreach($productIdList as $productID) + { + $product = new stdclass(); + + $product->draftStories = isset($productStories[$productID]) ? $productStories[$productID]['draft'] : 0; + $product->activeStories = isset($productStories[$productID]) ? $productStories[$productID]['active'] : 0; + $product->changingStories = isset($productStories[$productID]) ? $productStories[$productID]['changing'] : 0; + $product->reviewingStories = isset($productStories[$productID]) ? $productStories[$productID]['reviewing'] : 0; + $product->closedStories = isset($productStories[$productID]) ? $productStories[$productID]['closed'] : 0; + $product->finishedStories = isset($productStories[$productID]) ? $productStories[$productID]['finished'] : 0; + $product->totalStories = isset($productStories[$productID]) ? $productStories[$productID]['total'] : 0; + + $product->unresolvedBugs = isset($productBugs[$productID]) ? $productBugs[$productID]['unresolved'] : 0; + $product->closedBugs = isset($productBugs[$productID]) ? $productBugs[$productID]['closed'] : 0; + $product->fixedBugs = isset($productBugs[$productID]) ? $productBugs[$productID]['fixed'] : 0; + $product->totalBugs = isset($productBugs[$productID]) ? $productBugs[$productID]['total'] : 0; + + $product->plans = isset($plans[$productID]) ? $plans[$productID] : 0; + $product->releases = isset($releases[$productID]) ? $releases[$productID] : 0; + + $stats[$productID] = $product; + } + + return $stats; + } + + /** + * 获取产品下需求的统计数据。 + * Get story statistic data. + * + * @param array $productIdList + * @access protected + * @return array + */ + protected function getStoryStats(array $productIdList): array + { + $stories = $this->dao->select('product, status, `closedReason`, count(id) AS c') + ->from(TABLE_STORY) + ->where('deleted')->eq(0) + ->beginIF(!empty($productIdList))->andWhere('product')->in($productIdList)->fi() + ->andWhere('type')->eq('story') + ->groupBy('product, status, `closedReason`') + ->fetchAll(); + + $productStories = array(); + foreach($stories as $story) + { + if(!isset($productStories[$story->product])) $productStories[$story->product] = array('draft' => 0, 'active' => 0, 'changing' => 0, 'reviewing' => 0, 'finished' => 0, 'closed' => 0, 'total' => 0); + if($story->status == 'draft') $productStories[$story->product]['draft'] += $story->c; + if($story->status == 'active') $productStories[$story->product]['active'] += $story->c; + if($story->status == 'changing') $productStories[$story->product]['changing'] += $story->c; + if($story->status == 'reviewing') $productStories[$story->product]['reviewing'] += $story->c; + if($story->status == 'closed') $productStories[$story->product]['closed'] += $story->c; + $productStories[$story->product]['total'] += $story->c; + + if($story->status == 'closed' && $story->closedReason == 'done') $productStories[$story->product]['finished'] += $story->c; + } + + return $productStories; + } + + /** + * 获取产品下bug的统计数据。 + * Get bug statistic data. + * + * @param array $productIdList + * @access protected + * @return array + */ + protected function getBugStats(array $productIdList): array + { + $bugs = $this->dao->select('product,status,resolution, count(id) AS c') + ->from(TABLE_BUG) + ->where('deleted')->eq(0) + ->beginIF(!empty($productIdList))->andWhere('product')->in($productIdList)->fi() + ->groupBy('product, status, resolution') + ->fetchAll(); + + $productBugs = array(); + foreach($bugs as $bug) + { + if(!isset($productBugs[$bug->product])) $productBugs[$bug->product] = array('unresolved' => 0, 'fixed' => 0, 'closed' => 0, 'total' => 0); + if($bug->status == 'active' || ($bug->status != 'closed' && $bug->resolution == 'postponed')) $productBugs[$bug->product]['unresolved'] += $bug->c; + + if($bug->status == 'closed' && $bug->resolution == 'fixed') $productBugs[$bug->product]['fixed'] += $bug->c; + if($bug->status == 'closed') $productBugs[$bug->product]['closed'] += $bug->c; + $productBugs[$bug->product]['total'] += $bug->c; + } + + return $productBugs; + } }