* Finish task #43903.

This commit is contained in:
tianshujie
2021-11-05 08:59:55 +08:00
parent e893c7f6c3
commit 6cb70ab01d
17 changed files with 150 additions and 40 deletions
+1 -1
View File
@@ -837,7 +837,7 @@ CREATE TABLE IF NOT EXISTS `zt_projectproduct` (
`product` mediumint(8) unsigned NOT NULL,
`branch` mediumint(8) unsigned NOT NULL,
`plan` mediumint(8) unsigned NOT NULL,
PRIMARY KEY (`project`,`product`)
PRIMARY KEY (`project`,`product`, `branch`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- DROP TABLE IF EXISTS `zt_projectspec`;
CREATE TABLE IF NOT EXISTS `zt_projectspec` (
+1
View File
@@ -7,6 +7,7 @@ $lang->branch->add = 'Hinzufügen';
$lang->branch->manageTitle = '%s Management';
$lang->branch->all = 'Alle ';
$lang->branch->main = 'Trunk';
$lang->branch->id = 'ID';
$lang->branch->product = 'Produkt';
+1
View File
@@ -7,6 +7,7 @@ $lang->branch->add = 'Add';
$lang->branch->manageTitle = '%s Management';
$lang->branch->all = 'All ';
$lang->branch->main = 'Trunk';
$lang->branch->id = 'ID';
$lang->branch->product = 'Product';
+1
View File
@@ -7,6 +7,7 @@ $lang->branch->add = 'Ajout';
$lang->branch->manageTitle = 'Gestion %s';
$lang->branch->all = 'Tous';
$lang->branch->main = 'Trunk';
$lang->branch->id = 'ID';
$lang->branch->product = 'Product';
+1
View File
@@ -7,6 +7,7 @@ $lang->branch->add = 'Thêm';
$lang->branch->manageTitle = 'Quản lý %s';
$lang->branch->all = 'Tất cả ';
$lang->branch->main = 'Trunk';
$lang->branch->id = 'ID';
$lang->branch->product = 'Sản phẩm';
+1
View File
@@ -7,6 +7,7 @@ $lang->branch->add = '添加';
$lang->branch->manageTitle = '%s管理';
$lang->branch->all = '所有';
$lang->branch->main = '主干';
$lang->branch->id = '编号';
$lang->branch->product = '所属产品';
+4 -7
View File
@@ -25,7 +25,7 @@ class branchModel extends model
if(empty($productID)) $productID = $this->session->product;
$product = $this->loadModel('product')->getById($productID);
if(empty($product) or !isset($this->lang->product->branchName[$product->type])) return false;
return $this->lang->branch->all . $this->lang->product->branchName[$product->type];
return $this->lang->branch->main;
}
return htmlspecialchars_decode($this->dao->select('*')->from(TABLE_BRANCH)->where('id')->eq($branchID)->fetch('name'));
}
@@ -52,7 +52,7 @@ class branchModel extends model
$product = $this->loadModel('product')->getById($productID);
if(!$product or $product->type == 'normal') return array();
$branches = array('0' => $this->lang->branch->all . $this->lang->product->branchName[$product->type]) + $branches;
$branches = array('0' => $this->lang->branch->main) + $branches;
}
return $branches;
}
@@ -81,10 +81,7 @@ class branchModel extends model
}
}
if(strpos($params, 'noempty') === false)
{
$branchPairs = array('0' => $this->lang->branch->all . $this->lang->product->branchName['branch']) + $branchPairs;
}
if(strpos($params, 'noempty') === false) $branchPairs = array('0' => $this->lang->branch->main) + $branchPairs;
return $branchPairs;
}
@@ -154,7 +151,7 @@ class branchModel extends model
if($product->type == 'normal') continue;
if(!isset($branchGroups[$product->id])) $branchGroups[$product->id] = array();
if(strpos($params, 'noempty') === false) $branchGroups[$product->id] = array('0' => $this->lang->branch->all . $this->lang->product->branchName[$product->type]) + $branchGroups[$product->id];
if(strpos($params, 'noempty') === false) $branchGroups[$product->id] = array('0' => $this->lang->branch->main) + $branchGroups[$product->id];
}
return $branchGroups;
+1 -1
View File
@@ -1776,7 +1776,7 @@ class bug extends control
$relatedTasks = $this->dao->select('id, name')->from(TABLE_TASK)->where('id')->in($relatedTaskIdList)->fetchPairs();
$relatedBugs = $this->dao->select('id, title')->from(TABLE_BUG)->where('id')->in($relatedBugIdList)->fetchPairs();
$relatedCases = $this->dao->select('id, title')->from(TABLE_CASE)->where('id')->in($relatedCaseIdList)->fetchPairs();
$relatedBranch = array('0' => $this->lang->branch->all) + $this->dao->select('id, name')->from(TABLE_BRANCH)->where('id')->in($relatedBranchIdList)->fetchPairs();
$relatedBranch = array('0' => $this->lang->branch->main) + $this->dao->select('id, name')->from(TABLE_BRANCH)->where('id')->in($relatedBranchIdList)->fetchPairs();
$relatedBuilds = array('trunk' => $this->lang->trunk) + $this->dao->select('id, name')->from(TABLE_BUILD)->where('id')->in($relatedBuildIdList)->fetchPairs();
$relatedFiles = $this->dao->select('id, objectID, pathname, title')->from(TABLE_FILE)->where('objectType')->eq('bug')->andWhere('objectID')->in(@array_keys($bugs))->andWhere('extra')->ne('editor')->fetchGroup('objectID');
$relatedModules = $this->loadModel('tree')->getAllModulePairs('bug');
+1 -1
View File
@@ -1320,7 +1320,7 @@ class bugModel extends model
else
{
$this->config->bug->search['fields']['branch'] = $this->lang->product->branch;
$this->config->bug->search['params']['branch']['values'] = array('' => '') + $this->loadModel('branch')->getPairs($productID, 'noempty') + array('all' => $this->lang->branch->all);
$this->config->bug->search['params']['branch']['values'] = array('' => '', 0 => $this->lang->branch->main) + $this->loadModel('branch')->getPairs($productID, 'noempty') + array('all' => $this->lang->branch->all);
}
$this->loadModel('search')->setSearchParams($this->config->bug->search);
+13 -12
View File
@@ -402,18 +402,19 @@ $lang->pasteImgFail = "Failed to paste images. Try again later.";
$lang->pasteImgUploading = "Uploading...";
/* Time formats settings. */
if(!defined('DT_DATETIME1')) define('DT_DATETIME1', 'Y-m-d H:i:s');
if(!defined('DT_DATETIME2')) define('DT_DATETIME2', 'y-m-d H:i');
if(!defined('DT_MONTHTIME1'))define('DT_MONTHTIME1', 'n/d H:i');
if(!defined('DT_MONTHTIME2'))define('DT_MONTHTIME2', 'n/d H:i');
if(!defined('DT_DATE1')) define('DT_DATE1', 'Y-m-d');
if(!defined('DT_DATE2')) define('DT_DATE2', 'Ymd');
if(!defined('DT_DATE3')) define('DT_DATE3', 'Y/m/d');
if(!defined('DT_DATE4')) define('DT_DATE4', 'M d');
if(!defined('DT_DATE5')) define('DT_DATE5', 'j/n');
if(!defined('DT_TIME1')) define('DT_TIME1', 'H:i:s');
if(!defined('DT_TIME2')) define('DT_TIME2', 'H:i');
if(!defined('LONG_TIME')) define('LONG_TIME', '2059-12-31');
if(!defined('DT_DATETIME1')) define('DT_DATETIME1', 'Y-m-d H:i:s');
if(!defined('DT_DATETIME2')) define('DT_DATETIME2', 'y-m-d H:i');
if(!defined('DT_MONTHTIME1')) define('DT_MONTHTIME1', 'n/d H:i');
if(!defined('DT_MONTHTIME2')) define('DT_MONTHTIME2', 'n/d H:i');
if(!defined('DT_DATE1')) define('DT_DATE1', 'Y-m-d');
if(!defined('DT_DATE2')) define('DT_DATE2', 'Ymd');
if(!defined('DT_DATE3')) define('DT_DATE3', 'Y/m/d');
if(!defined('DT_DATE4')) define('DT_DATE4', 'M d');
if(!defined('DT_DATE5')) define('DT_DATE5', 'j/n');
if(!defined('DT_TIME1')) define('DT_TIME1', 'H:i:s');
if(!defined('DT_TIME2')) define('DT_TIME2', 'H:i');
if(!defined('LONG_TIME')) define('LONG_TIME', '2059-12-31');
if(!defined('MAIN')) define('MAIN', '0');
/* Datepicker. */
$lang->datepicker = new stdclass();
+11 -10
View File
@@ -402,18 +402,19 @@ $lang->pasteImgFail = "贴图失败,请稍后重试。";
$lang->pasteImgUploading = "正在上传图片,请稍后...";
/* 时间格式设置。*/
if(!defined('DT_DATETIME1')) define('DT_DATETIME1', 'Y-m-d H:i:s');
if(!defined('DT_DATETIME2')) define('DT_DATETIME2', 'y-m-d H:i');
if(!defined('DT_DATETIME1')) define('DT_DATETIME1', 'Y-m-d H:i:s');
if(!defined('DT_DATETIME2')) define('DT_DATETIME2', 'y-m-d H:i');
if(!defined('DT_MONTHTIME1')) define('DT_MONTHTIME1', 'n/d H:i');
if(!defined('DT_MONTHTIME2')) define('DT_MONTHTIME2', 'n月d日 H:i');
if(!defined('DT_DATE1')) define('DT_DATE1', 'Y-m-d');
if(!defined('DT_DATE2')) define('DT_DATE2', 'Ymd');
if(!defined('DT_DATE3')) define('DT_DATE3', 'Y年m月d日');
if(!defined('DT_DATE4')) define('DT_DATE4', 'n月j日');
if(!defined('DT_DATE5')) define('DT_DATE5', 'j/n');
if(!defined('DT_TIME1')) define('DT_TIME1', 'H:i:s');
if(!defined('DT_TIME2')) define('DT_TIME2', 'H:i');
if(!defined('LONG_TIME')) define('LONG_TIME', '2059-12-31');
if(!defined('DT_DATE1')) define('DT_DATE1', 'Y-m-d');
if(!defined('DT_DATE2')) define('DT_DATE2', 'Ymd');
if(!defined('DT_DATE3')) define('DT_DATE3', 'Y年m月d日');
if(!defined('DT_DATE4')) define('DT_DATE4', 'n月j日');
if(!defined('DT_DATE5')) define('DT_DATE5', 'j/n');
if(!defined('DT_TIME1')) define('DT_TIME1', 'H:i:s');
if(!defined('DT_TIME2')) define('DT_TIME2', 'H:i');
if(!defined('LONG_TIME')) define('LONG_TIME', '2059-12-31');
if(!defined('MAIN')) define('MAIN', '0');
/* datepicker 时间*/
$lang->datepicker = new stdclass();
+1 -1
View File
@@ -858,7 +858,7 @@ class productModel extends model
else
{
$this->config->product->search['fields']['branch'] = $this->lang->product->branch;
$this->config->product->search['params']['branch']['values'] = array('' => '') + $this->loadModel('branch')->getPairs($productID, 'noempty') + array('all' => $this->lang->branch->all);
$this->config->product->search['params']['branch']['values'] = array('' => '', '0' => $this->lang->branch->main) + $this->loadModel('branch')->getPairs($productID, 'noempty') + array('all' => $this->lang->branch->all);
}
$this->loadModel('search')->setSearchParams($this->config->product->search);
+18
View File
@@ -275,6 +275,24 @@ class productplanModel extends model
return array('' => '') + $planPairs;
}
/**
* Get plan list by story id list.
*
* @param string|array $storyIdList
* @access public
* @return array
*/
public function getListByStories($storyIdList)
{
if(empty($storyIdList)) return array();
return $this->dao->select('t3.*, t1.id as storyID')->from(TABLE_STORY)->alias('t1')
->leftJoin(TABLE_PLANSTORY)->alias('t2')->on('t1.id=t2.story')
->leftJoin(TABLE_PRODUCTPLAN)->alias('t3')->on('t2.plan=t3.id')
->where('t1.id')->in($storyIdList)
->andWhere('t3.deleted')->eq(0)
->fetchGroup('storyID', 'id');
}
/**
* Get plans for products
*
+50 -2
View File
@@ -1381,7 +1381,55 @@ class story extends control
*/
public function batchChangeBranch($branchID)
{
$storyIdList = !empty($_POST['storyIdList']) ? $this->post->storyIdList : die(js::locate($this->session->storyList, 'parent'));
/* Get the storyIdList value from the post. */
if(!empty($_POST['storyIdList'])) $storyIdList = $_POST['storyIdList'];
$storyIdList = $storyIdList ? $storyIdList : die(js::locate($this->session->storyList, 'parent'));
$plans = $this->loadModel('productplan')->getListByStories($storyIdList);
if(empty($confirm))
{
$stories = $this->story->getByList($storyIdList);
$conflictStotyIdList = '';
$normalStotyIdList = '';
/* Determine whether there are conflicting stories. */
foreach($storyIdList as $storyID)
{
/* If the story of a non-trunk branch needs to be changed to a non-trunk branch, judge whether there is a conflict in the plan. */
if($branchID and $stories[$storyID]->branch and $stories[$storyID]->branch != $branchID and isset($plans[$storyID]))
{
if(!empty($plan->branch) and $plan->branch != $branchID)
{
$conflictStotyIdList .= '[' . $storyID . ']';
break;
}
}
/* If a trunk story needs to be switched to a non-trunk branch to determine whether there is a conflicting plan. */
elseif($branchID and empty($stories[$storyID]->branch) and $plans[$storyID])
{
foreach($plans[$storyID] as $plan)
{
if(!empty($plan->branch) and $plan->branch != $branchID)
{
$conflictStotyIdList .= '[' . $storyID . ']';
break;
}
}
}
else
{
$normalStotyIdList .= $storyID . ',';
}
}
if($conflictStotyIdList)
{
$storyIdList = implode(',', $storyIdList);
$confirmURL = $this->createLink('story', 'batchChangeBranch', "branchID=$branchID&confirm=yes&storyIdList=$storyIdList");
$cancelURL = $this->createLink('story', 'batchChangeBranch', "branchID=$branchID&confirm=no&storyIdList=$normalStotyIdList");
die(js::confirm(sprintf($this->lang->story->confirmChangeBranch, $conflictStotyIdList), $confirmURL, $cancelURL));
}
}
if(!is_array($storyIdList)) $storyIdList = explode(',', $storyIdList);
$storyIdList = array_unique($storyIdList);
$allChanges = $this->story->batchChangeBranch($storyIdList, $branchID);
if(dao::isError()) die(js::error(dao::getError()));
@@ -2039,7 +2087,7 @@ class story extends control
$relatedStories = $this->dao->select('id,title')->from(TABLE_STORY) ->where('id')->in($relatedStoryIdList)->fetchPairs();
$relatedFiles = $this->dao->select('id, objectID, pathname, title')->from(TABLE_FILE)->where('objectType')->eq('story')->andWhere('objectID')->in($storyIdList)->andWhere('extra')->ne('editor')->fetchGroup('objectID');
$relatedSpecs = $this->dao->select('*')->from(TABLE_STORYSPEC)->where('`story`')->in($storyIdList)->orderBy('version desc')->fetchGroup('story');
$relatedBranch = array('0' => $this->lang->branch->all) + $this->dao->select('id, name')->from(TABLE_BRANCH)->where('id')->in($relatedBranchIdList)->fetchPairs();
$relatedBranch = array('0' => $this->lang->branch->main) + $this->dao->select('id, name')->from(TABLE_BRANCH)->where('id')->in($relatedBranchIdList)->fetchPairs();
$relatedModules = $this->loadModel('tree')->getAllModulePairs();
foreach($stories as $story)
+43 -3
View File
@@ -1692,7 +1692,44 @@ class storyModel extends model
$story->branch = $branchID;
$this->dao->update(TABLE_STORY)->data($story)->autoCheck()->where('id')->eq((int)$storyID)->exec();
if(!dao::isError()) $allChanges[$storyID] = common::createChanges($oldStory, $story);
if(!dao::isError())
{
/* If a trunk story to be switched to a non-trunk branch to cancel the association with other non-trunk branch plans. */
$removeUnlinkPlan = '';
$continueLinkPlan = '';
if(empty($oldStory->branch) and $branchID and isset($plans[$storyID]))
{
foreach($plans[$storyID] as $planID => $plan)
{
if(!empty($plan->branch) and $plan->branch != $branchID)
{
$removeUnlinkPlan = $planID . ',';
continue;
}
$continueLinkPlan = $planID . ',';
}
}
/* If a non-trunk story wants to switch to a non-trunk branch, cancel the association with other non-trunk branch plans. */
elseif($oldStory->branch and $branchID and isset($plans[$storyID]))
{
foreach($plans[$storyID] as $planID => $plan)
{
if(!empty($plan->branch) and $plan->branch != $branchID)
{
$removeUnlinkPlan = $planID . ',';
continue;
}
$continueLinkPlan = $planID . ',';
}
}
if($removeUnlinkPlan) $this->dao->delete()->from(TABLE_PLANSTORY)->where('story')->eq($storyID)->andWhere('plan')->in($removeUnlinkPlan)->exec();
if($continueLinkPlan)
{
$story->plan = $continueLinkPlan;
$this->dao->update(TABLE_STORY)->set('plan')->eq($continueLinkPlan)->where('id')->eq($storyID)->exec();
}
$allChanges[$storyID] = common::createChanges($oldStory, $story);
}
}
return $allChanges;
}
@@ -2413,6 +2450,7 @@ class storyModel extends model
$storyQuery = $storyQuery . ' AND `product` ' . helper::dbIN(array_keys($products));
if($excludeStories) $storyQuery = $storyQuery . ' AND `id` NOT ' . helper::dbIN($excludeStories);
if($this->app->moduleName == 'productplan') $storyQuery .= " AND `status` NOT IN ('closed') AND `parent` >= 0 ";
$allBranch = "`branch` = 'all'";
if($executionID != '')
{
foreach($products as $product) $branches[$product->branch] = $product->branch;
@@ -2430,9 +2468,11 @@ class storyModel extends model
}
elseif($branch)
{
$allBranch = "`branch` = 'all'";
if($branch and strpos($storyQuery, '`branch` =') === false) $storyQuery .= " AND `branch` in('0','$branch')";
if(strpos($storyQuery, $allBranch) !== false) $storyQuery = str_replace($allBranch, '1', $storyQuery);
}
elseif(strpos($storyQuery, $allBranch) !== false)
{
$storyQuery = str_replace($allBranch, '1', $storyQuery);
}
$storyQuery = preg_replace("/`plan` +LIKE +'%([0-9]+)%'/i", "CONCAT(',', `plan`, ',') LIKE '%,$1,%'", $storyQuery);
+1 -1
View File
@@ -1439,7 +1439,7 @@ class testcaseModel extends model
else
{
$this->config->testcase->search['fields']['branch'] = $this->lang->product->branch;
$this->config->testcase->search['params']['branch']['values'] = array('' => '') + $this->loadModel('branch')->getPairs($productID, 'noempty') + array('all' => $this->lang->branch->all);
$this->config->testcase->search['params']['branch']['values'] = array('' => '', '0' => $this->lang->branch->main) + $this->loadModel('branch')->getPairs($productID, 'noempty') + array('all' => $this->lang->branch->all);
}
if(!$this->config->testcase->needReview) unset($this->config->testcase->search['params']['status']['values']['wait']);
$this->config->testcase->search['actionURL'] = $actionURL;
+1 -1
View File
@@ -42,7 +42,7 @@ class testsuiteModel extends model
if($currentProduct->type != 'normal')
{
$this->app->loadLang('branch');
$branchName = $this->lang->branch->all . $this->lang->product->branchName[$currentProduct->type];
$branchName = $this->lang->branch->main;
$output .= "<div class='btn-group'><button id='currentBranch' type='button' class='btn btn-limit'>{$branchName} </button></div></div>";
}
$output .= '</div>';