This commit is contained in:
mayue
2022-11-14 17:10:35 +08:00
18 changed files with 122 additions and 41 deletions
+25 -12
View File
@@ -1888,19 +1888,19 @@ class bugModel extends model
/**
* Get bugs of a execution.
*
* @param int $executionID
* @param int $productID
* @param int $branchID
* @param int $build
* @param string $type
* @param int $param
* @param string $orderBy
* @param string $excludeBugs
* @param object $pager
* @param int $executionID
* @param int $productID
* @param int $branchID
* @param string|array $builds
* @param string $type
* @param int $param
* @param string $orderBy
* @param string $excludeBugs
* @param object $pager
* @access public
* @return array
*/
public function getExecutionBugs($executionID, $productID = 0, $branchID = 'all', $build = 0, $type = '', $param = 0, $orderBy = 'id_desc', $excludeBugs = '', $pager = null)
public function getExecutionBugs($executionID, $productID = 0, $branchID = 'all', $builds = 0, $type = '', $param = 0, $orderBy = 'id_desc', $excludeBugs = '', $pager = null)
{
$type = strtolower($type);
if(strpos($orderBy, 'pri_') !== false) $orderBy = str_replace('pri_', 'priOrder_', $orderBy);
@@ -1935,15 +1935,28 @@ class bugModel extends model
}
else
{
$condition = '';
if($builds)
{
if(!is_array($builds)) $builds = explode(',', $builds);
$conditions = array();
foreach($builds as $build)
{
if($build) $conditions[] = "FIND_IN_SET('$build', t1.openedBuild)";
}
$condition = join(' OR ', $conditions);
$condition = "($condition)";
}
$bugs = $this->dao->select("t1.*, IF(t1.`pri` = 0, {$this->config->maxPriValue}, t1.`pri`) as priOrder, IF(t1.`severity` = 0, {$this->config->maxPriValue}, t1.`severity`) as severityOrder")->from(TABLE_BUG)->alias('t1')
->leftJoin(TABLE_MODULE)->alias('t2')->on('t1.module=t2.id')
->where('t1.deleted')->eq(0)
->beginIF(!empty($productID) and $branchID !== 'all')->andWhere('t1.branch')->eq($branchID)->fi()
->beginIF(empty($build))->andWhere('t1.execution')->eq($executionID)->fi()
->beginIF(empty($builds))->andWhere('t1.execution')->eq($executionID)->fi()
->beginIF(!empty($productID))->andWhere('t1.product')->eq($productID)->fi()
->beginIF($type == 'unresolved')->andWhere('t1.status')->eq('active')->fi()
->beginIF($type == 'noclosed')->andWhere('t1.status')->ne('closed')->fi()
->beginIF($build)->andWhere("CONCAT(',', t1.openedBuild, ',') like '%,$build,%'")->fi()
->beginIF($condition)->andWhere("$condition")->fi()
->beginIF(!empty($param))->andWhere('t2.path')->like("%,$param,%")->andWhere('t2.deleted')->eq(0)->fi()
->beginIF($excludeBugs)->andWhere('t1.id')->notIN($excludeBugs)->fi()
->orderBy($orderBy)
+1 -1
View File
@@ -292,7 +292,7 @@ class build extends control
$this->view->storyPager = $storyPager;
$generatedBugPager = new pager($type == 'generatedBug' ? $recTotal : 0, $recPerPage, $type == 'generatedBug' ? $pageID : 1);
$this->view->generatedBugs = $this->bug->getExecutionBugs($build->execution, $build->product, 'all', $build->id, $type, $param, $type == 'generatedBug' ? $sort : 'status_desc,id_desc', '', $generatedBugPager);
$this->view->generatedBugs = $this->bug->getExecutionBugs($build->execution, $build->product, 'all', "$build->id,{$build->builds}", $type, $param, $type == 'generatedBug' ? $sort : 'status_desc,id_desc', '', $generatedBugPager);
$this->view->generatedBugPager = $generatedBugPager;
$this->executeHooks($buildID);
+1
View File
@@ -57,6 +57,7 @@ $lang->build->notice = new stdclass();
$lang->build->notice->changeProduct = "The {$lang->SRCommon}, bug, or the version of the submitted test order has been linked, and its {$lang->productCommon} cannot be modified";
$lang->build->notice->changeExecution = "The version of the submitted test order cannot be modified {$lang->executionCommon}";
$lang->build->notice->changeBuilds = "The version of the submitted test order cannot be modified builds";
$lang->build->notice->autoRelation = "The completed requirements, resolved bugs, and generated bugs under the relevant version will be automatically associated with the project version";
$lang->build->finishStories = " %s {$lang->SRCommon} sind abgeschlossen.";
$lang->build->resolvedBugs = ' %s Bugs sind gelöst.';
+1
View File
@@ -57,6 +57,7 @@ $lang->build->notice = new stdclass();
$lang->build->notice->changeProduct = "The {$lang->SRCommon}, bug, or the version of the submitted test order has been linked, and its {$lang->productCommon} cannot be modified";
$lang->build->notice->changeExecution = "The version of the submitted test order cannot be modified {$lang->executionCommon}";
$lang->build->notice->changeBuilds = "The version of the submitted test order cannot be modified builds";
$lang->build->notice->autoRelation = "The completed requirements, resolved bugs, and generated bugs under the relevant version will be automatically associated with the project version";
$lang->build->finishStories = " Finished {$lang->SRCommon} %s";
$lang->build->resolvedBugs = ' Resolved Bug %s';
+1
View File
@@ -57,6 +57,7 @@ $lang->build->notice = new stdclass();
$lang->build->notice->changeProduct = "The {$lang->SRCommon}, bug, or the version of the submitted test order has been linked, and its {$lang->productCommon} cannot be modified";
$lang->build->notice->changeExecution = "The version of the submitted test order cannot be modified {$lang->executionCommon}";
$lang->build->notice->changeBuilds = "The version of the submitted test order cannot be modified builds";
$lang->build->notice->autoRelation = "The completed requirements, resolved bugs, and generated bugs under the relevant version will be automatically associated with the project version";
$lang->build->finishStories = " {$lang->SRCommon} Terminées %s";
$lang->build->resolvedBugs = ' Bugs Résolus %s';
+1
View File
@@ -53,6 +53,7 @@ $lang->build->notice = new stdclass();
$lang->build->notice->changeProduct = "The {$lang->SRCommon}, bug, or the version of the submitted test order has been linked, and its {$lang->productCommon} cannot be modified";
$lang->build->notice->changeExecution = "The version of the submitted test order cannot be modified {$lang->executionCommon}";
$lang->build->notice->changeBuilds = "The version of the submitted test order cannot be modified builds";
$lang->build->notice->autoRelation = "The completed requirements, resolved bugs, and generated bugs under the relevant version will be automatically associated with the project version";
$lang->build->finishStories = " {$lang->SRCommon} đã kết thúc %s";
$lang->build->resolvedBugs = ' Bug đã giải quyết %s';
+1
View File
@@ -57,6 +57,7 @@ $lang->build->notice = new stdclass();
$lang->build->notice->changeProduct = "已经关联{$lang->SRCommon}、Bug或提交测试单的版本,不能修改其所属{$lang->productCommon}";
$lang->build->notice->changeExecution = "提交测试单的版本,不能修改其所属{$lang->executionCommon}";
$lang->build->notice->changeBuilds = "提交测试单的版本,不能修改关联版本";
$lang->build->notice->autoRelation = "相关版本下完成的需求、解决的Bug、产生的Bug将会自动关联到项目版本中";
$lang->build->finishStories = " 本次共完成 %s 个{$lang->SRCommon}";
$lang->build->resolvedBugs = ' 本次共解决 %s 个Bug';
+30
View File
@@ -347,6 +347,7 @@ class buildModel extends model
if(!dao::isError())
{
$buildID = $this->dao->lastInsertID();
$this->linkChildBuilds($buildID, $build->builds);
$this->file->updateObjectID($this->post->uid, $buildID, 'build');
$this->file->saveUpload('build', $buildID);
$this->loadModel('score')->create('build', 'create', $buildID);
@@ -386,6 +387,8 @@ class buildModel extends model
if(isset($build->branch) and $oldBuild->branch != $build->branch) $this->dao->update(TABLE_RELEASE)->set('branch')->eq($build->branch)->where('build')->eq($buildID)->exec();
if(!dao::isError())
{
$addBuilds = array_diff(explode(',', $build->builds), explode(',', $oldBuild->builds));
if($addBuilds) $this->linkChildBuilds($buildID, $addBuilds);
$this->file->updateObjectID($this->post->uid, $buildID, 'build');
return common::createChanges($oldBuild, $build);
}
@@ -561,6 +564,33 @@ class buildModel extends model
foreach($this->post->unlinkBugs as $unlinkBugID) $this->action->create('bug', $unlinkBugID, 'unlinkedfrombuild', '', $buildID);
}
/**
* Bugs and stories associated with child builds.
*
* @param int $buildID
* @param string $childBuilds
* @access public
* @return void
*/
public function linkChildBuilds($buildID, $childBuilds)
{
$build = $this->dao->select('bugs, stories')->from(TABLE_BUILD)->where('id')->eq($buildID)->fetch();
$buildList = $this->dao->select('bugs, stories')->from(TABLE_BUILD)->where('id')->in($childBuilds)->fetchAll();
foreach($buildList as $buildInfo)
{
if($buildInfo->bugs) $build->bugs .= ",{$buildInfo->bugs}";
if($buildInfo->stories) $build->stories .= ",{$buildInfo->stories}";
}
$build->bugs = explode(',', $build->bugs);
$build->bugs = join(',', array_filter($build->bugs));
$build->stories = explode(',', $build->stories);
$build->stories = join(',', array_filter($build->stories));
$this->dao->update(TABLE_BUILD)->data($build)->where('id')->eq($buildID)->exec();
}
/**
* Build action menu.
*
+2 -1
View File
@@ -45,7 +45,8 @@
<?php if($app->tab == 'project' && !empty($multipleProject)):?>
<tr>
<th><?php echo $lang->build->builds;?></th>
<td id='buildBox'><?php echo html::select('builds', array(), '', "class='form-control chosen' multiple");?></td>
<td id='buildBox'><?php echo html::select('builds[]', array(), '', "class='form-control chosen' multiple");?></td>
<td><?php echo $lang->build->notice->autoRelation;?></td>
</tr>
<?php endif;?>
<tr>
+7 -1
View File
@@ -47,7 +47,13 @@
<tr>
<th><?php echo $lang->build->builds;?></th>
<td id='buildBox'><?php echo html::select('builds[]', $builds, $build->builds, "class='form-control chosen' multiple $disabled");?></td>
<td><?php if($disabled) echo $lang->build->notice->changeBuilds;?></td>
<td>
<?php if($disabled):?>
<?php echo $lang->build->notice->changeBuilds;?>
<?php else:?>
<?php echo $lang->build->notice->autoRelation;?>
<?php endif;?>
</td>
</tr>
<?php elseif(!empty($multipleProject)):?>
<th><?php echo $lang->build->execution;?></th>
+1
View File
@@ -791,6 +791,7 @@ if(!helper::hasFeature('devops'))
unset($lang->mainNav->devops, $lang->mainNav->menuOrder[35]);
unset($lang->scrum->menu->devops, $lang->scrum->menuOrder[25]);
unset($lang->waterfall->menu->devops, $lang->waterfall->menuOrder[35]);
unset($lang->execution->menu->devops, $lang->execution->menuOrder[45]);
}
if(!helper::hasFeature('kanban'))
+1 -1
View File
@@ -221,7 +221,7 @@
<?php
$datatableId = $this->moduleName . ucfirst($this->methodName);
$useDatatable = (isset($config->datatable->$datatableId->mode) and $config->datatable->$datatableId->mode == 'datatable');
$vars = "executionID={$execution->id}&orderBy=%s&type=$type&param=$param&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}";
$vars = "executionID={$execution->id}&storyType=$storyType&orderBy=%s&type=$type&param=$param&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}";
if($useDatatable) include '../../common/view/datatable.html.php';
if(!$execution->hasProduct and !$execution->multiple)
+1 -1
View File
@@ -693,7 +693,7 @@ class projectrelease extends control
$this->config->bug->search['params']['resolvedBuild']['values'] = $this->config->bug->search['params']['openedBuild']['values'];
$searchModules = array();
$moduleGroups = $this->loadModel('tree')->getOptionMenu($release->product, 'story', 0, explode(',', $release->branch));
$moduleGroups = $this->loadModel('tree')->getOptionMenu($release->product, 'bug', 0, explode(',', $release->branch));
foreach($moduleGroups as $modules) $searchModules += $modules;
$this->config->bug->search['params']['module']['values'] = $searchModules;
+43 -19
View File
@@ -464,7 +464,6 @@ class release extends control
$this->session->set('storyList', inlink('view', "releaseID=$releaseID&type=story&link=true&param=" . helper::safe64Encode("&browseType=$browseType&queryID=$param")), 'product');
$release = $this->release->getById($releaseID);
$build = $this->loadModel('build')->getByID($release->build);
$this->commonAction($release->product);
$this->loadModel('story');
$this->loadModel('tree');
@@ -475,15 +474,21 @@ class release extends control
$pager = new pager($recTotal, $recPerPage, $pageID);
/* Build search form. */
$queryID = ($browseType == 'bySearch') ? (int)$param : 0;
unset($this->config->product->search['fields']['product']);
unset($this->config->product->search['fields']['project']);
$queryID = ($browseType == 'bySearch') ? (int)$param : 0;
$this->config->product->search['actionURL'] = $this->createLink('release', 'view', "releaseID=$releaseID&type=story&link=true&param=" . helper::safe64Encode('&browseType=bySearch&queryID=myQueryID'));
$this->config->product->search['queryID'] = $queryID;
$this->config->product->search['style'] = 'simple';
$this->config->product->search['params']['plan']['values'] = $this->loadModel('productplan')->getPairsForStory($release->product, $release->branch, 'skipParent|withMainPlan');
$this->config->product->search['params']['status'] = array('operator' => '=', 'control' => 'select', 'values' => $this->lang->story->statusList);
$this->config->product->search['params']['module']['values'] = $this->loadModel('tree')->getOptionMenu($release->product, 'story', 0, $release->branch);;
$searchModules = array();
$moduleGroups = $this->loadModel('tree')->getOptionMenu($release->product, 'story', 0, explode(',', $release->branch));;
foreach($moduleGroups as $modules) $searchModules += $modules;
$this->config->product->search['params']['module']['values'] = $searchModules;
if($this->session->currentProductType == 'normal')
{
unset($this->config->product->search['fields']['branch']);
@@ -491,20 +496,30 @@ class release extends control
}
else
{
$this->config->product->search['fields']['branch'] = $this->lang->product->branch;
$branchName = $this->loadModel('branch')->getById($release->branch);
$branches = array('' => '', BRANCH_MAIN => $this->lang->branch->main, $release->branch => $branchName);
$allBranchs = $this->loadModel('branch')->getPairs($release->product);
$branches = array('' => '', BRANCH_MAIN => $this->lang->branch->main);
foreach(explode(',', trim($release->branch, ',')) as $branchID) $branches[$branchID] = zget($allBranchs, $branchID);
$this->config->product->search['fields']['branch'] = sprintf($this->lang->product->branch, $this->lang->product->branchName[$release->productType]);
$this->config->product->search['params']['branch']['values'] = $branches;
}
$this->loadModel('search')->setSearchParams($this->config->product->search);
if($browseType == 'bySearch' or $build->execution == 0)
$builds = $this->loadModel('build')->getByList($release->build);
$executionIdList = array();
foreach($builds as $build)
{
$allStories = $this->story->getBySearch($release->product, "0,{$release->branch}", $queryID, 'id', $build->execution ? $build->execution : '', 'story', $release->stories, $pager);
if(empty($build->execution)) continue;
$executionIdList[$build->execution] = $build->execution;
}
if($browseType == 'bySearch')
{
$allStories = $this->story->getBySearch($release->product, $release->branch, $queryID, 'id', $executionIdList, 'story', $release->stories, $pager);
}
else
{
$allStories = $this->story->getExecutionStories($build->execution, $build->product, 0, 't1.`order`_desc', 'byBranch', $release->branch, 'story', $release->stories, $pager);
$allStories = $this->story->getExecutionStories($executionIdList, $build->product, 0, 't1.`order`_desc', 'byBranch', $release->branch, 'story', $release->stories, $pager);
}
$this->view->allStories = $allStories;
@@ -584,7 +599,6 @@ class release extends control
$this->session->set('bugList', inlink('view', "releaseID=$releaseID&type=$type&link=true&param=" . helper::safe64Encode("&browseType=$browseType&queryID=$param")), 'qa');
/* Set menu. */
$release = $this->release->getByID($releaseID);
$build = $this->loadModel('build')->getByID($release->build);
$this->commonAction($release->product);
/* Load pager. */
@@ -593,17 +607,24 @@ class release extends control
/* Build the search form. */
$this->loadModel('bug');
$queryID = ($browseType == 'bysearch') ? (int)$param : 0;
unset($this->config->bug->search['fields']['product']);
unset($this->config->bug->search['fields']['project']);
$queryID = ($browseType == 'bysearch') ? (int)$param : 0;
$this->config->bug->search['actionURL'] = $this->createLink('release', 'view', "releaseID=$releaseID&type=$type&link=true&param=" . helper::safe64Encode('&browseType=bySearch&queryID=myQueryID'));
$this->config->bug->search['queryID'] = $queryID;
$this->config->bug->search['style'] = 'simple';
$this->config->bug->search['params']['plan']['values'] = $this->loadModel('productplan')->getPairsForStory($release->product, $release->branch, 'skipParent|withMainPlan');
$this->config->bug->search['params']['execution']['values'] = $this->loadModel('product')->getExecutionPairsByProduct($release->product, $release->branch);
$this->config->bug->search['params']['openedBuild']['values'] = $this->loadModel('build')->getBuildPairs($release->product, $branch = 'all', $params = '');
$this->config->bug->search['params']['resolvedBuild']['values'] = $this->config->bug->search['params']['openedBuild']['values'];
$this->config->bug->search['params']['module']['values'] = $this->loadModel('tree')->getOptionMenu($release->product, 'bug', 0, $release->branch);
$searchModules = array();
$moduleGroups = $this->loadModel('tree')->getOptionMenu($release->product, 'bug', 0, explode(',', $release->branch));
foreach($moduleGroups as $modules) $searchModules += $modules;
$this->config->bug->search['params']['module']['values'] = $searchModules;
if($this->session->currentProductType == 'normal')
{
unset($this->config->bug->search['fields']['branch']);
@@ -611,28 +632,31 @@ class release extends control
}
else
{
$this->config->bug->search['fields']['branch'] = $this->lang->product->branch;
$branchName = $this->loadModel('branch')->getById($release->branch);
$branches = array('' => '', BRANCH_MAIN => $this->lang->branch->main, $release->branch => $branchName);
$allBranchs = $this->loadModel('branch')->getPairs($release->product);
$branches = array('' => '', BRANCH_MAIN => $this->lang->branch->main);
foreach(explode(',', trim($release->branch, ',')) as $branchID) $branches[$branchID] = zget($allBranchs, $branchID);
$this->config->bug->search['fields']['branch'] = sprintf($this->lang->product->branch, $this->lang->product->branchName[$release->productType]);
$this->config->bug->search['params']['branch']['values'] = $branches;
}
$this->loadModel('search')->setSearchParams($this->config->bug->search);
$builds = $this->loadModel('build')->getByList($release->build);
$allBugs = array();
$releaseBugs = $type == 'bug' ? $release->bugs : $release->leftBugs;
if($browseType == 'bySearch' or $build->execution == 0)
if($browseType == 'bySearch')
{
$allBugs = $this->bug->getBySearch($release->product, $release->branch, $queryID, 'id_desc', $releaseBugs, $pager);
}
elseif($build->execution)
else
{
if($type == 'bug')
{
$allBugs = $this->bug->getReleaseBugs($build->id, $release->product, $release->branch, $releaseBugs, $pager);
$allBugs = $this->bug->getReleaseBugs(array_keys($builds), $release->product, $release->branch, $releaseBugs, $pager);
}
elseif($type == 'leftBug')
{
$allBugs = $this->bug->getProductLeftBugs($build->id, $release->product, $release->branch, $releaseBugs, $pager);
$allBugs = $this->bug->getProductLeftBugs(array_keys($builds), $release->product, $release->branch, $releaseBugs, $pager);
}
}
+1
View File
@@ -1,5 +1,6 @@
#releaseList {font-size: 13px;}
td {overflow: hidden; text-overflow: ellipsis; white-space: nowrap;}
#releaseList tbody>tr:hover{background-color: unset!important;}
.main-table tbody>tr>td:first-child{padding: 2px 8px!important;}
.c-id {width: 60px}
+2 -2
View File
@@ -31,7 +31,7 @@ class releaseModel extends model
->fetch();
if(!$release) return false;
$release->builds = $this->dao->select('id, filePath, scmPath, name, project')->from(TABLE_BUILD)->where('id')->in($release->build)->fetchAll();
$release->builds = $this->dao->select('id, filePath, scmPath, name, execution, project')->from(TABLE_BUILD)->where('id')->in($release->build)->fetchAll();
$this->loadModel('file');
$release = $this->file->replaceImgURL($release, 'desc');
@@ -66,7 +66,7 @@ class releaseModel extends model
->page($pager)
->fetchAll();
$builds = $this->dao->select("t1.id, t1.name, IF(t2.name IS NOT NULL, t2.name, '') AS projectName, IF(t3.name IS NOT NULL, t3.name, '{$this->lang->trunk}') AS branchName")
$builds = $this->dao->select("t1.id, t1.name, t1.execution, IF(t2.name IS NOT NULL, t2.name, '') AS projectName, IF(t3.name IS NOT NULL, t3.name, '{$this->lang->trunk}') AS branchName")
->from(TABLE_BUILD)->alias('t1')
->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.project = t2.id')
->leftJoin(TABLE_BRANCH)->alias('t3')->on('t1.branch = t3.id')
+2 -2
View File
@@ -52,7 +52,7 @@
<th class='c-id'><?php echo $lang->release->id;?></th>
<th class="c-name"><?php echo $lang->release->name;?></th>
<th class='text-center c-build'><?php echo $lang->release->build;?></th>
<th class='text-center c-build'><?php echo $lang->release->project;?></th>
<th class='text-center c-project'><?php echo $lang->release->project;?></th>
<th class='text-center c-status'><?php echo $lang->release->status;?></th>
<th class='c-date text-center'><?php echo $lang->release->date;?></th>
<?php
@@ -82,7 +82,7 @@
<?php if($product->type != 'normal'):?>
<span class='label label-outline label-badge'><?php echo $build->branchName;?></span>
<?php endif;?>
<?php echo html::a($this->createLink('build', 'view', "buildID=$build->id"), $build->name);?>
<?php echo html::a($this->createLink($build->execution ? 'build' : 'projectbuild', 'view', "buildID=$build->id"), $build->name);?>
</td>
<td><?php echo $build->projectName;?></td>
<?php if($i == 1):?>
+1 -1
View File
@@ -357,7 +357,7 @@
foreach($release->builds as $build)
{
$buildDivision = $i == count($release->builds) ? '' : $lang->comma;
echo (($build->project) ? html::a($this->createLink('build', 'view', "buildID=$build->id"), $build->name, '_blank') : $build->name) . $buildDivision;
echo (($build->project) ? html::a($this->createLink($build->execution ? 'build' : 'projectbuild', 'view', "buildID=$build->id"), $build->name, '_blank') : $build->name) . $buildDivision;
$i++;
}
?>