This commit is contained in:
lanzongjun
2023-05-08 18:40:10 +08:00
27 changed files with 270 additions and 254 deletions
+3 -1
View File
@@ -1,4 +1,4 @@
FROM hub.qucheng.com/ci/zentao-ztf:php8-2023050808
FROM hub.qucheng.com/ci/zentao-ztf:php8-2023050810
# Install zentao
ARG VERSION
@@ -13,3 +13,5 @@ ENV MYSQL_PASSWORD=${MYSQL_PASSWORD}
SHELL ["/bin/bash", "-c"]
# Copy ZenTao
COPY --chown=33:33 . /apps/zentao/
RUN INIT_PHPINI_ONLY=true /etc/s6/s6-init/run
@@ -1,19 +0,0 @@
#!/usr/bin/env php
<?php
include dirname(__FILE__, 5) . "/test/lib/init.php";
include dirname(__FILE__, 2) . '/block.class.php';
su('admin');
/**
title=测试 blockModel->getHiddenBlocks();
cid=1
pid=1
测试获取隐藏的区块 >> 未获取到隐藏的区块
*/
$block = new blockTest();
r($block->getHiddenBlocksTest('my')) && p('message') && e('未获取到隐藏的区块'); //测试获取隐藏的区块
@@ -1,29 +0,0 @@
#!/usr/bin/env php
<?php
include dirname(__FILE__, 5) . "/test/lib/init.php";
include dirname(__FILE__, 2) . '/block.class.php';
su('admin');
/**
title=测试 blockModel->getStorysEstimateHours();
cid=1
pid=1
获取需求 1 的预计工时 >> 1
获取需求 2 的预计工时 >> 1
获取需求 3 的预计工时 >> 1
获取需求 4 的预计工时 >> 1
获取需求 5 的预计工时 >> 1
*/
$storyID = array(1, 2, 3, 4, 5);
$block = new blockTest();
r($block->getStorysEstimateHoursTest($storyID[0])) && p('estimate') && e('1'); // 获取需求 1 的预计工时
r($block->getStorysEstimateHoursTest($storyID[1])) && p('estimate') && e('1'); // 获取需求 2 的预计工时
r($block->getStorysEstimateHoursTest($storyID[2])) && p('estimate') && e('1'); // 获取需求 3 的预计工时
r($block->getStorysEstimateHoursTest($storyID[3])) && p('estimate') && e('1'); // 获取需求 4 的预计工时
r($block->getStorysEstimateHoursTest($storyID[4])) && p('estimate') && e('1'); // 获取需求 5 的预计工时
@@ -1,19 +0,0 @@
#!/usr/bin/env php
<?php
include dirname(__FILE__, 5) . "/test/lib/init.php";
include dirname(__FILE__, 2) . '/block.class.php';
su('admin');
/**
title=测试 blockModel->getWelcomeBlockData();
cid=1
pid=1
获取欢迎区块的数据 >> {"tasks":"0","doneTasks":"0","bugs":85,"stories":0,"executions":739,"products":80,"delayTask":0,"delayBug":74,"delayProject":0}
*/
$block = new blockTest();
r($block->getWelcomeBlockDataTest()) && p() && e('{"tasks":"0","doneTasks":"0","bugs":85,"stories":0,"executions":739,"products":80,"delayTask":0,"delayBug":74,"delayProject":0}'); // 获取欢迎区块的数据
+21 -44
View File
@@ -7,54 +7,31 @@ su('admin');
/**
title=测试 blockModel->initBlock();
timeout=0
cid=1
pid=1
获取敏捷项目的区块版本 >> 1;2
获取敏捷项目的区块数据 >> project;scrum
获取瀑布项目的区块版本 >> 1;2
获取瀑布项目的区块数据 >> project;waterfall
获取看板项目的区块版本 >> 1;2
获取看板项目的区块数据 >> project;kanban
获取产品的区块版本 >> 1;2
获取产品的区块数据 >> product;
获取执行的区块版本 >> 1;2
获取执行的区块数据 >> execution;
获取地盘的区块版本 >> 1;2
获取地盘的区块数据 >> my;
获取测试的区块版本 >> 1;2
获取测试的区块数据 >> qa;
获取空区块版本 >> 1;2
获取空区块数据 >> 0
- 测试获取正常的block的内容
- 属性account @admin
- 属性dashboard @my
- 属性module @welcome
- 属性code @welcome
- 属性title @欢迎
- 测试获取正常的block的内容
- 属性account @admin
- 属性dashboard @my
- 属性module @project
- 属性code @project
- 属性title @项目列表
*/
$block = new blockTest();
global $tester, $app;
$tester->loadModel('block');
$tester->block->reset('my');
$dataList = array();
$dataList[0] = $block->initBlockTest('project', 'scrum');
$dataList[1] = $block->initBlockTest('project', 'waterfall');
$dataList[2] = $block->initBlockTest('project', 'kanban');
$dataList[3] = $block->initBlockTest('product');
$dataList[4] = $block->initBlockTest('execution');
$dataList[5] = $block->initBlockTest('my');
$dataList[6] = $block->initBlockTest('qa');
$dataList[7] = $block->initBlockTest('');
r($dataList[0]) && p("blockInited;blockversion") && e('1;2'); // 获取敏捷项目的区块版本
r($dataList[0]) && p("blockData:module;blockData:type") && e('project;scrum'); // 获取敏捷项目的区块数据
r($dataList[1]) && p("blockInited;blockversion") && e('1;2'); // 获取瀑布项目的区块版本
r($dataList[1]) && p("blockData:module;blockData:type") && e('project;waterfall'); // 获取瀑布项目的区块数据
r($dataList[2]) && p("blockInited;blockversion") && e('1;2'); // 获取看板项目的区块版本
r($dataList[2]) && p("blockData:module;blockData:type") && e('project;kanban'); // 获取看板项目的区块数据
r($dataList[3]) && p("blockInited;blockversion") && e('1;2'); // 获取产品的区块版本
r($dataList[3]) && p("blockData:module;blockData:type") && e('product;'); // 获取产品的区块数据
r($dataList[4]) && p("blockInited;blockversion") && e('1;2'); // 获取执行的区块版本
r($dataList[4]) && p("blockData:module;blockData:type") && e('execution;'); // 获取执行的区块数据
r($dataList[5]) && p("blockInited;blockversion") && e('1;2'); // 获取地盘的区块版本
r($dataList[5]) && p("blockData:module;blockData:type") && e('my;'); // 获取地盘的区块数据
r($dataList[6]) && p("blockInited;blockversion") && e('1;2'); // 获取测试的区块版本
r($dataList[6]) && p("blockData:module;blockData:type") && e('qa;'); // 获取测试的区块数据
r($dataList[7]) && p("blockInited;blockversion") && e('1;2'); // 获取空区块版本
r($dataList[7]) && p("blockData") && e('0'); // 获取空区块数据
$tester->block->initBlock('my');
$newBlcoks = $tester->block->getMyDashboard('my');
r(reset($newBlcoks)) && p('account,dashboard,module,code,title') && e('admin,my,welcome,welcome,欢迎'); // 测试获取正常的block的内容
r(end($newBlcoks)) && p('account,dashboard,module,code,title') && e('admin,my,project,project,项目列表'); // 测试获取正常的block的内容
@@ -14,9 +14,9 @@ namespace zin;
/**
* 获取区块左侧的产品列表.
* Get product tabs on the left side.
*
* @param array $products
* @param string $blockNavCode
*
* @param array $products
* @param string $blockNavCode
* @access public
* @return array
*/
@@ -54,10 +54,10 @@ function getProductTabs($products, $blockNavCode): array
/**
* 获取区块右侧显示的项目信息.
* Get product statistical information.
*
* @param object $products
* @param string $blockNavID
* Get product statistical information.
*
* @param object $products
* @param string $blockNavID
* @access public
* @return array
*/
+13 -15
View File
@@ -14,9 +14,9 @@ namespace zin;
/**
* 获取区块左侧的项目列表.
* Get project tabs on the left side.
*
* @param array $projects
* @param string $blockNavCode
*
* @param array $projects
* @param string $blockNavCode
* @access public
* @return array
*/
@@ -54,10 +54,10 @@ function getProjectTabs($projects, $blockNavCode): array
/**
* 获取区块右侧显示的项目信息.
* Get project statistical information.
*
* @param object $projects
* @param string $blockNavID
* Get project statistical information.
*
* @param object $projects
* @param string $blockNavID
* @access public
* @return array
*/
@@ -80,8 +80,8 @@ function getProjectInfo($projects, $blockNavID): array
/**
* 获取敏捷类项目的统计信息.
* Get scrum project info.
*
* @param object $project
*
* @param object $project
* @access public
* @return void
*/
@@ -89,7 +89,7 @@ function getScrumProjectInfo($project)
{
global $lang;
$scrumProjectInfo = div
return div
(
/* 区块右侧顶部的项目概况。 */
div
@@ -158,14 +158,13 @@ function getScrumProjectInfo($project)
getProjectStatisticItems($project)
)
);
return $scrumProjectInfo;
}
/**
* 获取项目的统计项.
* get project statistic items.
*
* @param object $project
*
* @param object $project
* @access public
* @return array
*/
@@ -233,7 +232,7 @@ function getWaterfallProjectInfo($project)
{
global $app, $lang;
$isChineseLang = in_array($app->getClientLang(), array('zh-cn','zh-tw'));
$waterfallProjectInfo = div
return div
(
/* 瀑布项目展示概况。 */
set('class', 'weekly-row'),
@@ -343,7 +342,6 @@ function getWaterfallProjectInfo($project)
)
)
);
return $waterfallProjectInfo;
}
$blockNavCode = 'nav-' . uniqid();
+1 -1
View File
@@ -18,7 +18,7 @@ foreach($projects as $projectID => $project)
$cards[] = cell
(
set('width', '33%'),
set('class', 'border m-2 p-4'),
set('class', 'border m-2 p-4'),
div
(
set('class', 'pb-2'),
+1 -3
View File
@@ -1118,9 +1118,7 @@ class blockZen extends block
$this->loadModel('weekly');
$this->app->loadLang('execution');
$projectID = $this->session->project;
$project = $this->loadModel('project')->getByID($projectID);
$projectID = $this->session->project;
$projectWeekly = $this->dao->select('*')->from(TABLE_WEEKLYREPORT)->where('project')->eq($projectID)->orderBy('weekStart_asc')->fetchAll('weekStart');
$charts['PV'] = '[';
+3 -3
View File
@@ -380,7 +380,7 @@ class doc extends control
$libID = $this->post->lib;
$moduleID = $this->post->module;
if(empty($libID) and strpos($this->post->module, '_') !== false) list($libID, $moduleID) = explode('_', $this->post->module);
setcookie('lastDocModule', $moduleID, $this->config->cookieLife, $this->config->webRoot, '', $this->config->cookieSecure, false);
setcookie('lastDocModule', $moduleID, $this->config->cookieLife, $this->config->webRoot, '', $this->config->cookieSecure, true);
$docResult = $this->doc->create();
if(!$docResult or dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
@@ -1043,7 +1043,7 @@ class doc extends control
{
$this->loadModel('file');
if(empty($viewType)) $viewType = !empty($_COOKIE['docFilesViewType']) ? $this->cookie->docFilesViewType : 'list';
setcookie('docFilesViewType', $viewType, $this->config->cookieLife, $this->config->webRoot, '', false, true);
setcookie('docFilesViewType', $viewType, $this->config->cookieLife, $this->config->webRoot, '', $this->config->cookieSecure, true);
$objects = $this->doc->getOrderedObjects($type, 'nomerge', $objectID);
list($libs, $libID, $object, $objectID, $objectDropdown) = $this->doc->setMenuByType($type, $objectID, 0);
@@ -1271,7 +1271,7 @@ class doc extends control
$docSpaceParam->moduleID = $moduleID;
$docSpaceParam->browseType = $browseType;
$docSpaceParam->param = $param;
setCookie("docSpaceParam", json_encode($docSpaceParam), $this->config->cookieLife, $this->config->webRoot, '', false, true);
setCookie("docSpaceParam", json_encode($docSpaceParam), $this->config->cookieLife, $this->config->webRoot, '', $this->config->cookieSecure, true);
if($moduleID) $libID = $this->tree->getById($moduleID)->root;
$isFirstLoad = $libID == 0 ? true : false;
+6 -5
View File
@@ -524,8 +524,10 @@ class productTao extends productModel
* @access private
* @return string
*/
private function getBranchSelect4Mobile(object $product, string|int $branch, string $currentModule, string $currentMethod, string $extra = ''): string
protected function getBranchSelect4Mobile(object $product, string|int $branch, string $currentModule, string $currentMethod, string $extra = ''): string
{
if(!isset($product->type) or $product->type == 'normal') return '';
/* 修正分支显示语言项。 */
$this->lang->product->branch = sprintf($this->lang->product->branch, $this->lang->product->branchName[$product->type]);
$this->lang->product->menu->settings['subMenu']->branch['link'] = str_replace('@branch@', $this->lang->product->branch, $this->lang->product->menu->settings['subMenu']->branch['link']);
@@ -533,7 +535,7 @@ class productTao extends productModel
/* 生成分支HTML代码。*/
$output = '';
$branches = $this->loadModel('branch')->getPairs($product->id, 'all');
$branchName = zget($branches, $branch, '');
$branchName = zget($branches, $branch, reset($branches));
if($branchName) $output .= "<a id='currentBranch' href=\"javascript:showSearchMenu('branch', '{$product->id}', '$currentModule', '$currentMethod', '$extra')\">{$branchName} <span class='icon-caret-down'></span></a><div id='currentBranchDropMenu' class='hidden affix enter-from-bottom layer'></div>";
return $output;
@@ -743,8 +745,8 @@ class productTao extends productModel
if(!isset($products[$productID])) $productID = (int)key($products);
/* 检测当前页面是否在项目或执行的测试二级导航中。*/
$isQaModule = (strpos(',project,execution,', ",{$this->app->tab},") !== false and strpos(',bug,testcase,testtask,ajaxselectstory,', ",{$this->app->rawMethod},") !== false) ? true : false;
if($this->app->tab == 'project' and strpos(',zeroCase,browseUnits,groupCase,', ",$currentMethod,") !== false) $isQaModule = true;
$isQaModule = (strpos(',project,execution,', ",{$this->app->tab},") !== false and stripos(',bug,testcase,testtask,ajaxselectstory,', ",{$this->app->rawMethod},") !== false) ? true : false;
if($this->app->tab == 'project' and stripos(',zeroCase,browseUnits,groupCase,', ",$currentMethod,") !== false) $isQaModule = true;
if($isQaModule)
{
if($this->app->tab == 'project') $extra = strpos(',testcase,groupCase,zeroCase,', ",$currentMethod,") !== false ? $extra : $this->session->project;
@@ -753,7 +755,6 @@ class productTao extends productModel
/* 查询产品数据。*/
$currentProduct = $this->getById($productID);
if(empty($currentProduct)) return '';
$this->session->set('currentProductType', $currentProduct->type);
/* 生成异步获取下拉菜单的链接。*/
+30
View File
@@ -1139,4 +1139,34 @@ class productTest
return array('hasProduct' => $hasProduct, 'hasBranch' => $hasBranch);
}
/**
* 测试 buildSelect4Mobile 方法。
* Test buildSelect4Mobile
*
* @param array $products
* @param int $productID
* @param string $currentModule
* @param string $currentMethod
* @param string $extra
* @param string|int $branch
* @param bool $withBranch
* @access public
* @return array
*/
public function buildSelect4MobileTest(array $products, int $productID, string $currentModule, string $currentMethod, string $extra = '', string|int $branch = '', bool $withBranch = true): array
{
$this->objectModel->lang->product->menu->settings['subMenu']->branch = array('link' => "@branch@|branch|manage|product=%s", 'subModule' => 'branch');
$select = $this->objectModel->buildSelect4Mobile($products, $productID, $currentModule, $currentMethod, $extra, $branch, $withBranch);
$productName = zget($products, $productID, reset($products));
$branchName = '所有';
if(is_numeric($branch)) $branchName = $this->objectModel->dao->select('*')->from(TABLE_BRANCH)->where('id')->eq($branch)->fetch('name');
$hasProduct = (int)(strpos($select, 'currentItem') !== false and strpos($select, $productName) !== false);
$hasBranch = (int)(strpos($select, 'currentBranch') !== false and strpos($select, $branchName) !== false);
return array('hasProduct' => $hasProduct, 'hasBranch' => $hasBranch);
}
}
+52
View File
@@ -0,0 +1,52 @@
#!/usr/bin/env php
<?php
include dirname(__FILE__, 5) . "/test/lib/init.php";
include dirname(__FILE__, 2) . '/product.class.php';
zdTable('product')->gen(50);
$branch = zdTable('branch');
$branch->product->range('41');
$branch->gen(5);
/**
title=测试productModel->buildSelect4Mobile();
timeout=0
cid=1
*/
$productTest = new productTest('admin');
$productTest->objectModel->dao->update(TABLE_PRODUCT)->set('deleted')->eq(1)->where('id')->eq(49)->exec();
$products = $productTest->objectModel->dao->select('*')->from(TABLE_PRODUCT)->where('deleted')->eq(0)->fetchPairs('id', 'name');
$moduleName = 'product';
$methodName = 'browse';
r($productTest->buildSelect4MobileTest(array(), 0, $moduleName, $methodName)) && p('hasProduct,hasBranch') && e('0,0');
r($productTest->buildSelect4MobileTest($products, 0, $moduleName, $methodName)) && p('hasProduct,hasBranch') && e('1,0');
r($productTest->buildSelect4MobileTest($products, 1, $moduleName, $methodName)) && p('hasProduct,hasBranch') && e('1,0');
r($productTest->buildSelect4MobileTest($products, 49, $moduleName, $methodName)) && p('hasProduct,hasBranch') && e('1,0');
r($productTest->buildSelect4MobileTest($products, 41, $moduleName, $methodName)) && p('hasProduct,hasBranch') && e('1,1');
r($productTest->buildSelect4MobileTest($products, 41, $moduleName, $methodName, '', 1)) && p('hasProduct,hasBranch') && e('1,1');
r($productTest->buildSelect4MobileTest($products, 41, $moduleName, $methodName, '', '', false)) && p('hasProduct,hasBranch') && e('1,0');
r($productTest->buildSelect4MobileTest($products, 70, $moduleName, $methodName)) && p('hasProduct,hasBranch') && e('1,0');
$productTest->objectModel->app->tab = 'project';
$moduleName = 'project';
$methodName = 'testcase';
r($productTest->buildSelect4MobileTest($products, 41, $moduleName, $methodName)) && p('hasProduct,hasBranch') && e('1,1');
$moduleName = 'testcase';
$methodName = 'groupCase';
r($productTest->buildSelect4MobileTest($products, 41, $moduleName, $methodName)) && p('hasProduct,hasBranch') && e('1,1');
$productTest->objectModel->app->tab = 'execution';
$moduleName = 'execution';
$methodName = 'bug';
r($productTest->buildSelect4MobileTest($products, 41, $moduleName, $methodName)) && p('hasProduct,hasBranch') && e('1,1');
$methodName = 'task';
r($productTest->buildSelect4MobileTest($products, 41, $moduleName, $methodName)) && p('hasProduct,hasBranch') && e('1,1');
$productTest->objectModel->app->tab = 'feedback';
$moduleName = 'bug';
$methodName = 'view';
r($productTest->buildSelect4MobileTest($products, 41, $moduleName, $methodName)) && p('hasProduct,hasBranch') && e('1,1');
+32
View File
@@ -0,0 +1,32 @@
#!/usr/bin/env php
<?php
include dirname(__FILE__, 5) . "/test/lib/init.php";
zdTable('product')->gen(50);
$branch = zdTable('branch');
$branch->product->range('41');
$branch->gen(5);
/**
title=测试productModel->getBranchSelect4Mobile();
timeout=0
cid=1
*/
global $tester;
$productTest = $tester->loadModel('product');
$product = $productTest->dao->select('*')->from(TABLE_PRODUCT)->where('id')->eq(1)->fetch();
$moduleName = 'product';
$methodName = 'browse';
r($productTest->getBranchSelect4Mobile(new stdclass(), '', $moduleName, $methodName)) && p() && e('0');
r($productTest->getBranchSelect4Mobile($product, '', $moduleName, $methodName)) && p() && e('0');
$product = $productTest->dao->select('*')->from(TABLE_PRODUCT)->where('id')->eq(41)->fetch();
$result = $productTest->getBranchSelect4Mobile($product, 'all', $moduleName, $methodName);
r((strpos($result, 'currentBranch') !== false and strpos($result, '所有') !== false)) && p() && e('1');
$result = $productTest->getBranchSelect4Mobile($product, 1, $moduleName, $methodName);
r((strpos($result, 'currentBranch') !== false and strpos($result, '分支1') !== false)) && p() && e('1');
+44
View File
@@ -0,0 +1,44 @@
#!/usr/bin/env php
<?php
include dirname(__FILE__, 5) . "/test/lib/init.php";
zdTable('product')->gen(50);
$branch = zdTable('branch');
$branch->product->range('41');
$branch->gen(5);
/**
title=测试productModel->getBranchSelect4PC();
timeout=0
cid=1
*/
global $tester;
$productTest = $tester->loadModel('product');
$product = $productTest->dao->select('*')->from(TABLE_PRODUCT)->where('id')->eq(1)->fetch();
$moduleName = 'product';
$methodName = 'browse';
r($productTest->getBranchSelect4PC(new stdclass(), '', $moduleName, $methodName)) && p() && e('0');
r($productTest->getBranchSelect4PC($product, '', $moduleName, $methodName)) && p() && e('0');
$product = $productTest->dao->select('*')->from(TABLE_PRODUCT)->where('id')->eq(41)->fetch();
$result = $productTest->getBranchSelect4PC($product, '', $moduleName, $methodName);
r((strpos($result, 'currentBranch') !== false and strpos($result, '所有') !== false)) && p() && e('1');
$result = $productTest->getBranchSelect4PC($product, 1, $moduleName, $methodName);
r((strpos($result, 'currentBranch') !== false and strpos($result, '分支1') !== false)) && p() && e('1');
r((strpos($productTest->getBranchSelect4PC($product, 1, 'testcase', 'showimport'), 'currentBranch') !== false)) && p() && e('0');
r((strpos($productTest->getBranchSelect4PC($product, 1, 'tree', 'browse'), 'currentBranch') !== false)) && p() && e('1');
r((strpos($productTest->getBranchSelect4PC($product, 1, 'product', 'view'), 'currentBranch') !== false)) && p() && e('0');
r((strpos($productTest->getBranchSelect4PC($product, 1, 'release', 'create'), 'currentBranch') !== false)) && p() && e('1');
r((strpos($productTest->getBranchSelect4PC($product, 1, 'release', 'view'), 'currentBranch') !== false)) && p() && e('0');
$productTest->app->tab = 'qa';
r((strpos($productTest->getBranchSelect4PC($product, 1, 'bug', 'view'), 'currentBranch') !== false)) && p() && e('1');
r((strpos($productTest->getBranchSelect4PC($product, 1, 'testcase', 'view'), 'currentBranch') !== false)) && p() && e('1');
r((strpos($productTest->getBranchSelect4PC($product, 1, 'testtask', 'view'), 'currentBranch') !== false)) && p() && e('1');
r((strpos($productTest->getBranchSelect4PC($product, 1, 'testtask', 'create'), 'currentBranch') !== false)) && p() && e('0');
+8 -8
View File
@@ -630,10 +630,10 @@ class projectTao extends projectModel
* @param int $program
* @param string $path
* @param int $grade
* @access public
* @access protected
* @return string
*/
public function getParentProgram(string $path, int $grade): string
protected function getParentProgram(string $path, int $grade): string
{
$programList = $this->dao->select('id,name')->from(TABLE_PROGRAM)
->where('id')->in(trim($path, ','))
@@ -761,10 +761,10 @@ class projectTao extends projectModel
* Get the number of stories associated with the project.
*
* @param array $projectIdList
* @access public
* @access protected
* @return array
*/
public function getTotalStoriesByProject(array $projectIdList): array
protected function getTotalStoriesByProject(array $projectIdList): array
{
return $this->dao->select("t1.project, count(t2.id) as allStories, count(if(t2.status = 'active' or t2.status = 'changing', 1, null)) as leftStories, count(if(t2.status = 'closed' and t2.closedReason = 'done', 1, null)) as doneStories")->from(TABLE_PROJECTSTORY)->alias('t1')
->leftJoin(TABLE_STORY)->alias('t2')->on('t1.story=t2.id')
@@ -780,10 +780,10 @@ class projectTao extends projectModel
* Get the number of tasks associated with the project.
*
* @param array $projectIdList
* @access public
* @access protected
* @return array
*/
public function getTotalTaskByProject(array $projectIdList): array
protected function getTotalTaskByProject(array $projectIdList): array
{
return $this->dao->select("t1.project, count(t1.id) as allTasks, count(if(t1.status = 'wait', 1, null)) as waitTasks, count(if(t1.status = 'doing', 1, null)) as doingTasks, count(if(t1.status = 'done', 1, null)) as doneTasks, count(if(t1.status = 'wait' or t1.status = 'pause' or t1.status = 'cancel', 1, null)) as leftTasks, count(if(t1.status = 'done' or t1.status = 'closed', 1, null)) as litedoneTasks")->from(TABLE_TASK)->alias('t1')
->leftJoin(TABLE_EXECUTION)->alias('t2')->on('t1.execution=t2.id')
@@ -812,10 +812,10 @@ class projectTao extends projectModel
* Get the number of bugs associated with the project.
*
* @param array $projectIdList
* @access public
* @access protected
* @return array
*/
public function getTotalBugByProject(array $projectIdList): array
protected function getTotalBugByProject(array $projectIdList): array
{
return $this->dao->select("project, count(id) as allBugs, count(if(status = 'active', 1, null)) as leftBugs, count(if(status = 'resolved', 1, null)) as doneBugs")->from(TABLE_BUG)
->where('project')->in($projectIdList)
+1
View File
@@ -3916,6 +3916,7 @@ class taskModel extends model
/* If both of lane id and column id are not empty, add task to the kanban cell. */
if($laneID and $columnID) $this->kanban->addKanbanCell($kanbanID, $laneID, $columnID, 'task', $task->id);
/* If lane id or column id is empty, update the task type lane of the kanban. */
if(!$laneID or !$columnID) $this->kanban->updateLane($kanbanID, 'task');
}
+12 -5
View File
@@ -60,8 +60,15 @@ $testTasks[3]->type = 'test';
$testTasks[3]->mailto = '';
$taskTester = new taskTest();
r($taskTester->afterCreateTest(1, $taskIdList['test'], 1)) && p('toTask') && e('1'); // 测试Bug转任务后,更新Bug的信息
r($taskTester->afterCreateTest(2, $taskIdList['todo'], 0, 1)) && p('status') && e('done'); // 测试待办转任务后,更新待办的信息
r($taskTester->afterCreateTest(3, $taskIdList['design'])) && p('designVersion') && e('1'); // 测试任务关联设计后,更新任务中的designVersion字段
r($taskTester->afterCreateTest(4, $taskIdList['story'])) && p('stage') && e('planned'); // 测试任务关联需求后,更新需求的阶段
r($taskTester->afterCreateTest(1, $taskIdList['test'], 0, 0, $testTasks)) && p('parent') && e('-1'); // 测试任务创建子任务后,父任务的parent字段的值
r($taskTester->afterCreateTest()) && p() && e('0'); // 测试空数据
r($taskTester->afterCreateTest(0, $taskIdList['test'])) && p() && e('0'); // 测试taskID为空的情况
r($taskTester->afterCreateTest(5, $taskIdList['test'])) && p() && e('0'); // 测试taskID不存在的情况
r($taskTester->afterCreateTest(1)) && p('name') && e('测试任务1'); // 测试taskIdList为空的情况
r($taskTester->afterCreateTest(1, array(), 1)) && p('title') && e('Bug1'); // 测试taskIdList为空,但是有BugID的情况
r($taskTester->afterCreateTest(1, array(), 0, 1)) && p('name') && e('待办1'); // 测试taskIdList为空,但是有todoID的情况
r($taskTester->afterCreateTest(1, array(), 0, 0, $testTasks)) && p('name') && e('测试任务1'); // 测试taskIdList为空,但是有testTasks的情况
r($taskTester->afterCreateTest(1, $taskIdList['test'], 1)) && p('toTask') && e('1'); // 测试Bug转任务后,更新Bug的信息
r($taskTester->afterCreateTest(2, $taskIdList['todo'], 0, 1)) && p('status') && e('done'); // 测试待办转任务后,更新待办的信息
r($taskTester->afterCreateTest(3, $taskIdList['design'])) && p('designVersion') && e('1'); // 测试任务关联设计后,更新任务中的designVersion字段
r($taskTester->afterCreateTest(4, $taskIdList['story'])) && p('stage') && e('planned'); // 测试任务关联需求后,更新需求的阶段
r($taskTester->afterCreateTest(1, $taskIdList['test'], 0, 0, $testTasks)) && p('parent') && e('-1'); // 测试任务创建子任务后,父任务的parent字段的值
+6 -3
View File
@@ -1763,15 +1763,18 @@ class taskTest
* @param int $todoID
* @param array $testTasks
* @access public
* @return object
* @return object|bool
*/
public function afterCreateTest($taskID, $taskIdList, $bugID = 0, $todoID = 0, $testTasks = array())
public function afterCreateTest($taskID = 0, $taskIdList = array(), $bugID = 0, $todoID = 0, $testTasks = array())
{
global $tester;
$_SERVER['HTTP_HOST'] = $tester->config->db->host;
$task = $this->objectModel->getByID($taskID);
$this->objectModel->afterCreate($task, $taskIdList, $bugID, $todoID, $testTasks);
if(!$task) return false;
$result = $this->objectModel->afterCreate($task, $taskIdList, $bugID, $todoID, $testTasks);
if(!$result) return false;
if($bugID)
{
+15 -45
View File
@@ -126,7 +126,7 @@ function loadList(type, id, objectID)
* 选择开始时间后,自动给出默认终止时间。
* After selecting the start time, the default end time is automatically given.
*
* @return viod
* @return void
*/
function selectNext()
{
@@ -135,49 +135,6 @@ function selectNext()
$('#end').trigger('chosen:updated');
}
function setBeginsAndEnds(i, beginOrEnd)
{
if(!i)
{
for(j = 0; j < batchCreateNum; j++)
{
if(j != 0) $('#begins' + j)[0].selectedIndex = $('#ends' + (j - 1))[0].selectedIndex;
$('#ends' + j)[0].selectedIndex = $('#begins' + j)[0].selectedIndex + 3;
$('#begins' + j, '#ends' + j).trigger('chosen:updated');
}
}
else
{
if(beginOrEnd == 'begin')
{
$('#ends' + i)[0].selectedIndex = $('#begins' + i)[0].selectedIndex + 3;
$('#ends' + i).trigger('chosen:updated');
}
if(batchCreateNum)
{
for(j = i+1; j < batchCreateNum; j++)
{
$('#begins' + j)[0].selectedIndex = $('#ends' + (j - 1))[0].selectedIndex;
$('#ends' + j)[0].selectedIndex = $('#begins' + j)[0].selectedIndex + 3;
$('#begins' + j, '#ends' + j).trigger('chosen:updated');
}
}
}
}
function switchTimeList(number)
{
if($('#switchTime' + number).prop('checked'))
{
$('#begins' + number, '#ends' + number).attr('disabled', 'disabled').trigger('chosen:updated');
}
else
{
$('#begins' + number, '#ends' + number).removeAttr('disabled').trigger('chosen:updated');
}
}
/**
* 切换起止时间的禁用状态。
* Switch the disabled state of start and end time.
@@ -238,7 +195,7 @@ function showEvery(switcher)
* 周期设置为天并为指定时,更改月份时获取天数。
* When the cycle is set to days and specified, obtain the number of days when changing the month.
*
* @param int $specifiedMonth
* @param int specifiedMonth
* @return void
*/
function setDays(specifiedMonth)
@@ -259,3 +216,16 @@ function setDays(specifiedMonth)
$('#specifiedDay').append(html);
}
}
/**
* 更改日期。
* Change date.
*
* @param object dateInput
* @return void
*/
function changeDate(dateInput)
{
console.log(dateInput);
$('#switchDate').prop('checked', !$(dateInput).val());
}
+3 -3
View File
@@ -4,7 +4,7 @@ selectNext();
* 切换周期类型,用于展示周期类型的交互。
* Toggle cycle, used to display the interaction of cycle.
*
* @param object tab
* @param object switcher
* @return void
*/
function toggleCycle(switcher)
@@ -31,12 +31,12 @@ function toggleCycle(switcher)
* 更改待办日期。
* Change todo date.
*
* @param object tab
* @param object dateInput
* @return void
*/
function changeCreateDate(dateInput)
{
$('#switchDate').prop('checked', !$(dateInput).val());
changeDate(dateInput);
var selectTime = $(dateInput).val() != today ? start : nowTime;
$('#begin').val(selectTime);
$('#begin').trigger('chosen:updated');
-12
View File
@@ -13,15 +13,3 @@ function changeType(typeSelect)
{
loadList($(typeSelect).find('select').val(), '', idvalue);
}
/**
* 更改待办日期。
* Change todo date.
*
* @param object tab
* @return void
*/
function changeCreateDate(dateInput)
{
$('#switchDate').prop('checked', !$(dateInput).val());
}
+4 -1
View File
@@ -31,9 +31,11 @@ formPanel
set::width('1/2'),
input
(
set::class('date'),
set::name('date'),
set::type('date'),
set::value(date('Y-m-d'))
set::value(date('Y-m-d')),
on::change('changeDate(this)')
)
),
formGroup
@@ -41,6 +43,7 @@ formPanel
set::class(array('items-center', 'pl-2')),
checkbox
(
set::id('switchDate'),
set::name('future'),
set::text($lang->todo->periods['future']),
on::change('togglePending(this)')
+1 -1
View File
@@ -77,7 +77,7 @@ function buildDateControl(object $todo)
'type' => 'date',
'width' => '1/4'
)),
on::change('changeCreateDate(this)')
on::change('changeDate(this)')
),
),
formGroup
+1 -1
View File
@@ -2046,7 +2046,7 @@ class treeModel extends model
break;
}
if(strpos($this->session->{$module->type . 'List'}, 'param=' . $moduleID)) $this->session->set($module->type . 'List', str_replace('param=' . $moduleID, 'param=0', $this->session->{$module->type . 'List'}));
if($cookieName) setcookie($cookieName, 0, time() - 3600, $this->config->webRoot, '', $this->config->cookieSecure, false);
if($cookieName) setcookie($cookieName, 0, time() - 3600, $this->config->webRoot, '', $this->config->cookieSecure, true);
return true;
}
+6
View File
@@ -16,6 +16,8 @@ fields:
range: 分支
- field: name2
range: 1-10000
- field: desc
range: ""
- field: status
range: active,closed
- field: order
@@ -25,6 +27,10 @@ fields:
postfix: ""
loop: 0
format: ""
- field: createdDate
range: "(-3M)-(+M):1D"
type: timestamp
format: "YY/MM/DD"
- field: deleted
note: "是否删除"
range: 0
@@ -1,29 +0,0 @@
#!/usr/bin/env php
<?php
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
include dirname(dirname(dirname(__FILE__))) . '/class/block.class.php';
su('admin');
/**
title=测试 blockModel->getStorysEstimateHours();
cid=1
pid=1
获取需求 1 的预计工时 >> 1
获取需求 2 的预计工时 >> 1
获取需求 3 的预计工时 >> 1
获取需求 4 的预计工时 >> 1
获取需求 5 的预计工时 >> 1
*/
$storyID = array(1, 2, 3, 4, 5);
$block = new blockTest();
r($block->getStorysEstimateHoursTest($storyID[0])) && p('estimate') && e('1'); // 获取需求 1 的预计工时
r($block->getStorysEstimateHoursTest($storyID[1])) && p('estimate') && e('1'); // 获取需求 2 的预计工时
r($block->getStorysEstimateHoursTest($storyID[2])) && p('estimate') && e('1'); // 获取需求 3 的预计工时
r($block->getStorysEstimateHoursTest($storyID[3])) && p('estimate') && e('1'); // 获取需求 4 的预计工时
r($block->getStorysEstimateHoursTest($storyID[4])) && p('estimate') && e('1'); // 获取需求 5 的预计工时