Merge branch 'master' into 'fixbug_cyy'

# Conflicts:
#   module/install/model.php
This commit is contained in:
李玉春
2022-03-23 05:04:41 +00:00
23 changed files with 79 additions and 42 deletions

View File

@@ -79,7 +79,7 @@ class bugsEntry extends entry
if(!$productID and isset($this->requestBody->product)) $productID = $this->requestBody->product;
if(!$productID) return $this->sendError(400, 'Need product id.');
$fields = 'title,project,execution,openedBuild,assignedTo,pri,severity,type,story,task,mailto,keywords,steps';
$fields = 'title,project,execution,openedBuild,assignedTo,pri,module,severity,type,story,task,mailto,keywords,steps';
$this->batchSetPost($fields);
$this->setPost('product', $productID);

View File

@@ -22,7 +22,7 @@ class storyChangeEntry extends Entry
{
$oldStory = $this->loadModel('story')->getByID($storyID);
$fields = 'reviewer,comment';
$fields = 'reviewer,comment,executions,bugs,cases,tasks';
$this->batchSetPost($fields);
$fields = 'title,spec,verify';
$this->batchSetPost($fields, $oldStory);

View File

@@ -36,8 +36,8 @@ class taskRecordEstimateEntry extends Entry
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
$effort = array();
if($this->config->edition != 'open' and $data->data->efforts) $effort = $data->data->efforts;
if($this->config->edition == 'open' and $data->data->esitimates) $effort = $data->data->esitimates;
if($this->config->edition != 'open' and $data->data->efforts) $effort = $data->data->efforts;
if($this->config->edition == 'open' and $data->data->estimates) $effort = $data->data->estimates;
$this->send(200, array('effort' => $effort));
}

View File

@@ -297,9 +297,10 @@ class baseHelper
if(!empty($config->encryptSecret) and $password)
{
$secret = $config->encryptSecret;
$iv = str_repeat("\0", 8);
if(function_exists('mcrypt_encrypt'))
{
$encrypted = base64_encode(@mcrypt_encrypt(MCRYPT_DES, substr($secret, 0, 8), $password, MCRYPT_MODE_CBC));
$encrypted = base64_encode(mcrypt_encrypt(MCRYPT_DES, substr($secret, 0, 8), $password, MCRYPT_MODE_CBC, $iv));
}
elseif(function_exists('openssl_encrypt'))
{
@@ -307,7 +308,7 @@ class baseHelper
$oversize = strlen($password) % 8;
if($oversize != 0) $password .= str_repeat("\0", 8 - $oversize);
$encrypted = @openssl_encrypt($password, 'DES-CBC', substr($secret, 0, 8), OPENSSL_ZERO_PADDING);
$encrypted = openssl_encrypt($password, 'DES-CBC', substr($secret, 0, 8), OPENSSL_ZERO_PADDING, $iv);
}
}
if(empty($encrypted)) $encrypted = $password;
@@ -331,13 +332,14 @@ class baseHelper
if(!empty($config->encryptSecret) and $password)
{
$secret = $config->encryptSecret;
$iv = str_repeat("\0", 8);
if(function_exists('mcrypt_decrypt'))
{
$decryptedPassword = @mcrypt_decrypt(MCRYPT_DES, substr($secret, 0, 8), base64_decode($password), MCRYPT_MODE_CBC);
$decryptedPassword = trim(mcrypt_decrypt(MCRYPT_DES, substr($secret, 0, 8), base64_decode($password), MCRYPT_MODE_CBC, $iv));
}
elseif(function_exists('openssl_decrypt'))
{
$decryptedPassword = openssl_decrypt($password, 'DES-CBC', substr($secret, 0, 8), OPENSSL_ZERO_PADDING);
$decryptedPassword = trim(openssl_decrypt($password, 'DES-CBC', substr($secret, 0, 8), OPENSSL_ZERO_PADDING, $iv));
}
/* Check decrypted password. Judge whether there is garbled code. */

View File

@@ -431,7 +431,7 @@ class actionModel extends model
$name = $this->dao->select('name')->from(TABLE_TESTTASK)->where('id')->eq($action->extra)->fetch('name');
if($name) $action->extra = common::hasPriv('testtask', 'view') ? html::a(helper::createLink('testtask', 'view', "taskID=$action->extra"), $name) : $name;
}
elseif($actionName == 'tostory')
elseif($action->objectType != 'feedback' and $actionName == 'tostory')
{
$title = $this->dao->select('title')->from(TABLE_STORY)->where('id')->eq($action->extra)->fetch('title');
if($title) $action->extra = common::hasPriv('story', 'view') ? html::a(helper::createLink('story', 'view', "storyID=$action->extra"), "#$action->extra " . $title) : "#$action->extra " . $title;
@@ -462,7 +462,7 @@ class actionModel extends model
}
$action->extra = trim(trim($action->extra), ',');
}
elseif($actionName == 'totask' or $actionName == 'linkchildtask' or $actionName == 'unlinkchildrentask' or $actionName == 'linkparenttask' or $actionName == 'unlinkparenttask' or $actionName == 'deletechildrentask')
elseif($action->objectType != 'feedback' and (strpos(',totask,linkchildtask,unlinkchildrentask,linkparenttask,unlinkparenttask,deletechildrentask,', ",$actionName,") !== false))
{
$name = $this->dao->select('name')->from(TABLE_TASK)->where('id')->eq($action->extra)->fetch('name');
if($name) $action->extra = common::hasPriv('task', 'view') ? html::a(helper::createLink('task', 'view', "taskID=$action->extra"), "#$action->extra " . $name) : "#$action->extra " . $name;

View File

@@ -178,7 +178,7 @@ class blockModel extends model
->andWhere('t3.deleted')->eq('0')
->beginIF(!$this->app->user->admin)->andWhere('t1.execution')->in($this->app->user->view->sprints)->fi()
->beginIF($this->config->vision)->andWhere('t1.vision')->eq($this->config->vision)->fi()
->beginIF($this->config->vision)->andWhere('t2.vision')->eq($this->config->vision)->fi()
->beginIF($this->config->vision)->andWhere('t3.vision')->eq($this->config->vision)->fi()
->fetchAll('id');
$data['tasks'] = isset($tasks) ? count($tasks) : 0;
$data['doneTasks'] = (int)$this->dao->select('count(*) AS count')->from(TABLE_TASK)->where('assignedTo')->eq($this->app->user->account)->andWhere('deleted')->eq(0)->andWhere('status')->eq('done')->fetch('count');

View File

@@ -1644,6 +1644,8 @@ EOD;
*/
public static function buildMoreButton($executionID)
{
if(defined('TUTORIAL')) return;
global $lang, $app;
$object = $app->dbh->query('SELECT project,type FROM ' . TABLE_EXECUTION . " WHERE `id` = '$executionID'")->fetch();

View File

@@ -1020,6 +1020,7 @@ function updateKanban(kanbanData, regionID = 0)
{
setTimeout(function()
{
$.zui.closeModal();
if(regionID)
{
updateRegion(regionID, kanbanData[regionID]);

View File

@@ -232,6 +232,8 @@ class executionModel extends model
*/
public function saveState($executionID, $executions)
{
if(defined('TUTORIAL')) return $executionID;
/* When the cookie and session do not exist, get it from the database. */
if(empty($executionID) and isset($this->config->execution->lastExecution) and isset($executions[$this->config->execution->lastExecution]))
{

View File

@@ -2507,8 +2507,7 @@ class kanbanModel extends model
$otherCardList = '';
$otherLanes = $this->dao->select('t2.id, t2.cards')->from(TABLE_KANBANLANE)->alias('t1')
->leftJoin(TABLE_KANBANCELL)->alias('t2')->on('t1.id=t2.lane')
->where('t1.deleted')->eq(0)
->andWhere('t1.id')->ne($lane->id)
->where('t1.id')->ne($lane->id)
->andWhere('t1.execution')->eq($executionID)
->andWhere('t2.`type`')->eq($lane->type)
->fetchPairs();

View File

@@ -44,11 +44,11 @@
echo "<div class='divider'></div>";
}
common::printLink('kanban', 'editCard', "cardID=$card->id", '<i class="icon icon-edit"></i>', '', "class='btn btn-link iframe' data-width='80%' title='{$lang->kanbancard->edit}'", true, true);
common::printLink('kanban', 'editCard', "cardID=$card->id", '<i class="icon icon-edit"></i>', '', "class='btn btn-link' data-width='80%' title='{$lang->kanbancard->edit}'", true, true);
if($kanban->performable)
{
if($card->status == 'done') echo html::a(helper::createLink('kanban', 'activateCard', "cardID={$card->id}&kanbanID={$kanban->id}"), '<i class="icon icon-magic"></i>', '', "class='btn btn-link iframe' title='{$lang->kanban->activateCard}'");
if($card->status == 'done') echo html::a(helper::createLink('kanban', 'activateCard', "cardID={$card->id}&kanbanID={$kanban->id}"), '<i class="icon icon-magic"></i>', '', "class='btn btn-link' title='{$lang->kanban->activateCard}'");
if($card->status == 'doing') echo html::a(helper::createLink('kanban', 'finishCard', "cardID={$card->id}&kanbanID={$kanban->id}"), '<i class="icon icon-checked"></i>', '', "class='btn btn-link iframe' title='{$lang->kanban->finishCard}'");
}

View File

@@ -148,6 +148,8 @@ class productModel extends model
*/
public function saveState($productID, $products)
{
if(defined('TUTORIAL')) return $productID;
if($productID == 0 and $this->cookie->preProductID) $productID = $this->cookie->preProductID;
if(($productID == 0 and $this->session->product == '') or !isset($products[$productID])) $productID = key($products);
$this->session->set('product', (int)$productID, $this->app->tab);

View File

@@ -117,6 +117,8 @@ class projectModel extends model
*/
public function saveState($projectID = 0, $projects = array())
{
if(defined('TUTORIAL')) return $projectID;
if($projectID == 0 and $this->cookie->lastProject) $projectID = $this->cookie->lastProject;
if($projectID == 0 and $this->session->project == '') $projectID = key($projects);
$this->session->set('project', (int)$projectID, $this->app->tab);

View File

@@ -1 +1,3 @@
.pl-10px {padding-left: 10px;}
#showAllModuleBox{width:60px;}
#showAllModuleBox .no-margin {padding-left:22px;}

View File

@@ -1,2 +1,3 @@
.thWidth {width: 85px !important;}
.lifeThWidth {width: 120px !important;}
#showAllModuleBox{width:50px;}

View File

@@ -1,2 +1,3 @@
.thWidth {width: 93px !important;}
.lifeThWidth {width: 80px !important;}
#showAllModuleBox{width:60px;}

View File

@@ -1,2 +1,3 @@
.thWidth {width: 80px !important;}
.lifeThWidth {width: 80px !important;}
#showAllModuleBox{width:60px;}

View File

@@ -101,9 +101,9 @@
<td>
<div class='table-row'>
<span class='table-col' id="moduleIdBox"><?php echo html::select('module', $modules, $task->module, 'class="form-control chosen" onchange="loadModuleRelated()"');?></span>
<span class='table-col w-100px text-middle pl-10px'>
<span class='table-col text-middle pl-10px' id='showAllModuleBox'>
<div class="checkbox-primary">
<input type="checkbox" id="showAllModule" <?php if($showAllModule) echo 'checked';?>><label for="showAllModule" class="no-margin"><?php echo $lang->task->allModule;?></label>
<input type="checkbox" id="showAllModule" <?php if($showAllModule) echo 'checked';?>><label for="showAllModule" class="no-margin"><?php echo $lang->all;?></label>
</div>
</span>
</div>

View File

@@ -210,28 +210,35 @@ class storyTest
if(dao::isError()) return dao::getError();
global $tester;
return $tester->loadModel('story')->getById($storyID);
}
public function updateStoryVersionTest($story)
{
$objects = $this->objectModel->updateStoryVersion($story);
if(dao::isError()) return dao::getError();
return $objects;
return $this->objectModel->getById($storyID);
}
/**
* Test update story order of plan.
*
* @param int $storyID
* @param string $planIDList
* @param string $oldPlanIDList
* @access public
* @return void
*/
public function updateStoryOrderOfPlanTest($storyID, $planIDList = '', $oldPlanIDList = '')
{
$objects = $this->objectModel->updateStoryOrderOfPlan($storyID, $planIDList = '', $oldPlanIDList = '');
$this->objectModel->updateStoryOrderOfPlan($storyID, $planIDList, $oldPlanIDList);
if(dao::isError()) return dao::getError();
return $objects;
global $tester;
return $tester->dao->select('*')->from(TABLE_PLANSTORY)->where('plan')->in($planIDList)->fetchAll();
}
/**
* Test compute estimate.
*
* @param int $storyID
* @access public
* @return void
*/
public function computeEstimateTest($storyID)
{
$objects = $this->objectModel->computeEstimate($storyID);
@@ -241,13 +248,22 @@ class storyTest
return $objects;
}
public function batchUpdateTest()
/**
* Test batch update stories.
*
* @access public
* @return void
*/
public function batchUpdateTest($params)
{
$objects = $this->objectModel->batchUpdate();
$_POST = $params;
$allStories = $this->objectModel->batchUpdate();
unset($_POST);
if(dao::isError()) return dao::getError();
return $objects;
$storyIdList = array_keys($allStories);
return $this->objectModel->getByList($storyIdList);
}
public function reviewTest($storyID)

View File

@@ -5,14 +5,14 @@ version: "1.0"
fields:
- field: story
note: "需求ID"
range: 1-20
range: 1-30
prefix: ""
postfix: ""
loop: 0
format: ""
- field: version
note: "版本"
range: 1{20},2{20},3{20}
range: 1{30},2{30},3{20}
prefix: ""
postfix: ""
loop: 0

View File

@@ -18,7 +18,7 @@ $builder->sprint = array('rows' => 600, 'extends' => array('project', 'ex
$builder->story = array('rows' => 400, 'extends' => array('story'));
$builder->storymodule = array('rows' => 800, 'extends' => array('module','storymodule'));
$builder->storyplan = array('rows' => 400, 'extends' => array('planstory'));
$builder->storyspec = array('rows' => 60, 'extends' => array('storyspec'));
$builder->storyspec = array('rows' => 80, 'extends' => array('storyspec'));
$builder->relation = array('rows' => 12, 'extends' => array('relation'));
$builder->task = array('rows' => 600, 'extends' => array('task','task'));
$builder->taskmore = array('rows' => 300, 'extends' => array('task','moretask'));

View File

@@ -22,13 +22,13 @@ $story2['reviewer'] = array('admin', 'test2');
$story2['title'] = '';
$story3 = $story1;
$story3['reviewer'] = array('admin', 'test2');
$story3['needNotReview'] = true;
$result1 = $story->changeTest(1, $story1);
$result2 = $story->changeTest(2, $story2);
$result3 = $story->changeTest(3, $story3);
$result1 = $story->changeTest(1, $story1);
$result2 = $story->changeTest(2, $story2);
$result3 = $story->changeTest(26, $story3);
r($result1[0]) && p() && e('『由谁评审』不能为空。'); // 不勾选【不需要评审】,不传入由谁评审时的变更,给出提示
r($result2) && p('title:0') && e('『研发需求名称』不能为空。'); // 变更时不填写需求名称,给出提示
r($result3) && p('status,title,spec,verify,estimate,lastEditedBy') && e('changed,测试需求1变更标题,测试需求1的变更描述,测试需求1的变更验收标准,1,admin'); // 正常变更需求判断返回的status、title等信息
r($result3) && p('status,title,spec,verify,estimate,lastEditedBy,version') && e('changed,测试需求1变更标题,测试需求1的变更描述,测试需求1的变更验收标准,1,admin,3'); // 正常变更需求判断返回的status、title等信息
system("./ztest init");

View File

@@ -12,5 +12,11 @@ pid=1
*/
$story = new storyTest();
$planStories1 = $story->updateStoryOrderOfPlanTest(1, 1);
$planStories2 = $story->updateStoryOrderOfPlanTest(1, 2, 1);
r() && p() && e();
r($planStories1) && p("0:plan,story,order") && e('1,1,21'); // 把需求1迁移到计划1下获取更新后的planstory
r(count($planStories1)) && p() && e('4'); // 把需求1迁移到计划1下获取更新后的planstory数量
r($planStories2) && p("0:plan,story,order") && e('2,1,1'); // 把需求1迁移到计划2下获取更新后的planstory
r(count($planStories2)) && p() && e('1'); // 把需求1迁移到计划2下获取更新后的planstory数量
system("./ztest init");