This commit is contained in:
王怡栋
2022-04-06 13:14:16 +08:00
31 changed files with 160 additions and 82 deletions
+1 -3
View File
@@ -95,14 +95,12 @@ class storyEntry extends Entry
$oldStory = $this->loadModel('story')->getByID($storyID);
/* Set $_POST variables. */
$fields = 'title,product,reviewer,type,plan,module,source,sourceNote,category,pri,estimate,mailto,keywords,uid,stage,notifyEmail';
$fields = 'title,product,parent,reviewer,type,plan,module,source,sourceNote,category,pri,estimate,mailto,keywords,uid,stage,notifyEmail';
$this->batchSetPost($fields, $oldStory);
$this->setPost('parent', 0);
$control = $this->loadController('story', 'edit');
$control->edit($storyID);
$data = $this->getData();
if(isset($data->status) and $data->status == 'fail') return $this->sendError(400, $data->message);
@@ -23,4 +23,5 @@ $lang->execution->icons['grouptask'] = 'sitemap';
$lang->execution->aclList['private'] = "Private (Accessible to team members and project leaders)";
$lang->execution->common = 'Project Execution';
$lang->execution->common = 'Project Execution';
$lang->execution->gantt = 'Gantt Chart';
@@ -24,4 +24,4 @@ $lang->execution->icons['grouptask'] = 'sitemap';
$lang->execution->aclList['private'] = "私有(团队成员和项目负责人可访问)";
$lang->execution->common = '项目看板';
$lang->execution->common = '项目看板';
+1 -1
View File
@@ -144,7 +144,7 @@
</table>
<?php endif;?>
<?php if($api->responseExample):?>
<h3><?php echo $lang->api->responseExample;?></h3>
<h3 class='title'><?php echo $lang->api->responseExample;?></h3>
<pre><code><?php echo $api->responseExample;?></code></pre>
<?php endif;?>
</div>
+1 -1
View File
@@ -541,7 +541,7 @@ class bug extends control
else
{
$builds = $this->loadModel('build')->getBuildPairs($productID, $branch, 'noempty,noterminate,nodone,withbranch');
$stories = $this->story->getProductStoryPairs($productID, $branch);
$stories = $this->story->getProductStoryPairs($productID, $branch, 0, 'all','id_desc', 0, 'full', 'story', false);
}
$moduleOwner = $this->bug->getModuleOwner($moduleID, $productID);
+4 -4
View File
@@ -2403,13 +2403,13 @@ EOD;
/* Limited execution. */
$limitedExecution = false;
if(!empty($module) && $module == 'task' && !empty($object->execution) or
!empty($module) && $module == 'execution' && !empty($object->id)
if(!empty($module) && in_array($module, array('task', 'story')) && !empty($object->execution) or
!empty($module) && $module == 'execution' && !empty($object->id)
)
{
$objectID = '';
if($module == 'execution' and !empty($object->id)) $objectID = $object->id;
if($module == 'task' and !empty($object->execution))$objectID = $object->execution;
if($module == 'execution' and !empty($object->id)) $objectID = $object->id;
if(in_array($module, array('task', 'story')) and !empty($object->execution)) $objectID = $object->execution;
$limitedExecutions = !empty($_SESSION['limitedExecutions']) ? $_SESSION['limitedExecutions'] : '';
if($objectID and strpos(",{$limitedExecutions},", ",$objectID,") !== false) $limitedExecution = true;
+11 -9
View File
@@ -1,5 +1,4 @@
<?php
/**
* The control file of doc module of ZenTaoPMS.
*
@@ -538,14 +537,15 @@ class doc extends control
$this->view->position[] = html::a($this->createLink('doc', 'browse', "libID=$doc->lib"), $lib->name);
$this->view->position[] = $this->lang->doc->view;
$this->view->doc = $doc;
$this->view->lib = $lib;
$this->view->type = $type;
$this->view->version = $version ? $version : $doc->version;
$this->view->actions = $this->action->getList('doc', $docID);
$this->view->users = $this->user->getPairs('noclosed,noletter');
$this->view->preAndNext = $this->loadModel('common')->getPreAndNextObject('doc', $docID);
$this->view->keTableCSS = $this->doc->extractKETableCSS($doc->content);
$this->view->doc = $doc;
$this->view->lib = $lib;
$this->view->type = $type;
$this->view->version = $version ? $version : $doc->version;
$this->view->actions = $this->action->getList('doc', $docID);
$this->view->users = $this->user->getPairs('noclosed,noletter');
$this->view->preAndNext = $this->loadModel('common')->getPreAndNextObject('doc', $docID);
$this->view->keTableCSS = $this->doc->extractKETableCSS($doc->content);
$this->view->autoloadPage = $this->doc->checkAutoloadPage($doc);
$this->display();
}
@@ -1067,6 +1067,8 @@ class doc extends control
$this->view->actions = $docID ? $this->action->getList('doc', $docID) : array();
$this->view->users = $this->user->getPairs('noclosed,noletter');
$this->view->preAndNext = $this->doc->getPreAndNextDoc($docID, $libID);
$this->view->autoloadPage = $this->doc->checkAutoloadPage($doc);
$this->display();
}
+21
View File
@@ -2651,4 +2651,25 @@ EOT;
return array($libs, $libID, $object, $objectID);
}
/**
* Whether the url of link type documents needs to be autoloaded.
*
* @param object $doc
* @access public
* @return bool
*/
public function checkAutoloadPage($doc)
{
$autoloadPage = true;
if(!empty($doc) and $doc->type == 'url')
{
$parsedUrl = parse_url($doc->content);
$urlPort = isset($parsedUrl['port']) ? ':' . $parsedUrl['port'] : '';
$urlDomain = $parsedUrl['host'] . $urlPort;
if($urlDomain == $_SERVER['HTTP_HOST']) $autoloadPage = false;
}
return $autoloadPage;
}
}
+1 -1
View File
@@ -74,7 +74,7 @@ $sessionString .= session_name() . '=' . session_id();
</p>
<?php endif;?>
<?php
if($doc->type == 'url')
if($doc->type == 'url' and $autoloadPage)
{
$url = $doc->content;
if(!preg_match('/^https?:\/\//', $doc->content)) $url = 'http://' . $url;
+1 -1
View File
@@ -89,7 +89,7 @@ js::set('docID', $doc->id);
<div class="detail no-padding">
<div class="detail-content article-content no-margin no-padding">
<?php
if($doc->type == 'url')
if($doc->type == 'url' and $autoloadPage)
{
$url = $doc->content;
if(!preg_match('/^https?:\/\//', $doc->content)) $url = 'http://' . $url;
+1
View File
@@ -1270,6 +1270,7 @@ class executionModel extends model
$executions = $this->dao->select('*')->from(TABLE_EXECUTION)
->where('type')->in('stage,sprint,kanban')
->andWhere('deleted')->eq('0')
->andWhere('vision')->eq($this->config->vision)
->beginIF($projectID)->andWhere('project')->eq((int)$projectID)->fi()
->beginIF(!$this->app->user->admin)->andWhere('id')->in($this->app->user->view->sprints)->fi()
->beginIF($status == 'undone')->andWhere('status')->notIN('done,closed')->fi()
+8 -4
View File
@@ -179,12 +179,15 @@
<thead>
<tr>
<?php
$checkObject = new stdclass();
$checkObject->execution = $execution->id;
$totalEstimate = 0;
$canBatchEdit = common::hasPriv('story', 'batchEdit');
$canBatchClose = common::hasPriv('story', 'batchClose');
$canBatchChangeStage = common::hasPriv('story', 'batchChangeStage');
$canBatchUnlink = common::hasPriv('execution', 'batchUnlinkStory');
$canBatchToTask = common::hasPriv('story', 'batchToTask');
$canBatchToTask = common::hasPriv('story', 'batchToTask', $checkObject);
$canBatchAction = ($canBeChanged and ($canBatchEdit or $canBatchClose or $canBatchChangeStage or $canBatchUnlink or $canBatchToTask));
?>
<?php $vars = "executionID={$execution->id}&orderBy=%s&type=$type&param=$param&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}"; ?>
@@ -335,13 +338,14 @@
$actionLink = $this->createLink('story', 'batchEdit', "productID=0&executionID=$execution->id");
echo html::commonButton($lang->edit, "data-form-action='$actionLink' $disabled");
?>
<button type='button' <?php echo $canBatchToTask ? '' : "disabled='disabled'";?> class='btn dropdown-toggle' data-toggle='dropdown'><span class='caret'></span></button>
<?php if($canBatchToTask):?>
<button type='button' class='btn dropdown-toggle' data-toggle='dropdown'><span class='caret'></span></button>
<ul class='dropdown-menu'>
<?php
$class = $canBatchToTask ? '' : "class='hidden'";
echo "<li $class>" . html::a('#batchToTask', $lang->story->batchToTask, '', "data-toggle='modal' id='batchToTaskButton'") . "</li>";
echo "<li>" . html::a('#batchToTask', $lang->story->batchToTask, '', "data-toggle='modal' id='batchToTaskButton'") . "</li>";
?>
</ul>
<?php endif;?>
</div>
<?php
if($canBatchClose)
+1 -1
View File
@@ -286,7 +286,7 @@ body {margin-bottom: 25px;}
</thead>
<tbody>
<?php foreach($tasks as $task):?>
<tr data-id='<?php echo $task->id;?>' data-status='<?php echo $task->status?>' data-estimate='<?php echo $task->estimate?>' data-consumed='<?php echo $task->consumed?>' data-left='<?php echo $task->left?>'>
<tr <?php if(!empty($task->children)) echo 'class="table-parent" '; ?>data-id='<?php echo $task->id;?>' data-status='<?php echo $task->status?>' data-estimate='<?php echo $task->estimate?>' data-consumed='<?php echo $task->consumed?>' data-left='<?php echo $task->left?>'>
<?php if($this->app->getViewType() == 'xhtml'):?>
<?php
foreach($customFields as $field)
+4 -1
View File
@@ -126,7 +126,10 @@ class groupModel extends model
*/
public function getPairs($projectID = 0)
{
return $this->dao->select('id, name')->from(TABLE_GROUP)->where('project')->eq($projectID)->orderBy('id')->fetchPairs();
return $this->dao->select('id, name')->from(TABLE_GROUP)
->where('project')->eq($projectID)
->andWhere('vision')->eq($this->config->vision)
->orderBy('id')->fetchPairs();
}
/**
+4 -4
View File
@@ -36,14 +36,14 @@
.region .kanban-header {border-bottom: none!important; min-width: max-content; min-width: -moz-max-content;}
.region .kanban-header-col > .title {max-width: 80% !important;}
.region .kanban-header-col > .title {margin: 0}
.region .kanban-header-col > .title > span {display: inline-block; overflow: hidden; padding-right:2px; position: initial; max-width:95px !important;}
.region .kanban-header-col > .title > span {display: inline-block; overflow: hidden; padding-right:2px; position: initial; max-width:95px !important; vertical-align: middle;}
.region .kanban-header-col > .title > .text-grey {opacity: .5; font-weight: bold; color: #8b91a2;}
.region .kanban-header-col > .title > .count {opacity: .5; font-weight: bold; color: #8b91a2;}
.region .kanban-header-col > .title > .error {color: #333333; padding-left: 2px; font-size: 10px; padding-top: 1px; padding-right: 2px;}
.kanban-affixed .kanban-header-col > .title > .text {color: #fff!important}
.region .kanban-header-col > .actions {position: relative;}
.region .kanban-header-parent-col > .actions {position: absolute; right: 0px;}
.region .kanban-header-sub-cols .actions {position: absolute; right: 0px;}
.region .kanban-header-col > .actions {position: inherit; top: 30%;}
.region .kanban-header-parent-col > .actions {position: absolute; right: 0px; top: 0px !important;}
.region .kanban-header-sub-cols .actions {position: absolute; right: 0px; top: 0px !important;}
.region .kanban-lane {position: relative; border-bottom: none!important; min-height: 200px !important}
-3
View File
@@ -80,7 +80,4 @@ $(function()
});
$('#productListForm').on('checkChange', updateCheckboxes);
updateCheckboxes();
/* Disable animation for large rows */
$('#productListForm').toggleClass('no-animation', $('#productTableList>tr').length > 40)
});
+1 -1
View File
@@ -125,7 +125,7 @@ class programplan extends control
$this->programplan->create($projectID, $this->productID, $planID);
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
$locate = $this->createLink('project', 'execution', "status=all&projectID=$projectID");
$locate = $this->createLink('project', 'execution', "status=all&projectID=$projectID&orderBy=order_asc&productID=$productID");
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $locate));
}
+3 -3
View File
@@ -2364,7 +2364,7 @@ class story extends control
$relatedBranchIdList[$story->branch] = $story->branch;
$relatedStoryIds[$story->id] = $story->id;
if(isset($relations[$story->id])) $story->linkStories = $story->linkStories . ',' . $relations[$story->id];
if(isset($relations[$story->id])) $story->childStories = $story->childStories . ',' . $relations[$story->id];
/* Process related stories. */
$relatedStories = $story->childStories . ',' . $story->linkStories . ',' . $story->duplicateStory;
@@ -2455,8 +2455,6 @@ class story extends control
$linkStoriesIdList = explode(',', $story->linkStories);
foreach($linkStoriesIdList as $linkStoryID)
{
if(empty($linkStoryID)) continue;
$linkStoryID = trim($linkStoryID);
$tmpLinkStories[] = isset($relatedStories[$linkStoryID]) ? $relatedStories[$linkStoryID] : $linkStoryID;
}
@@ -2469,6 +2467,8 @@ class story extends control
$childStoriesIdList = explode(',', $story->childStories);
foreach($childStoriesIdList as $childStoryID)
{
if(empty($childStoryID)) continue;
$childStoryID = trim($childStoryID);
$tmpChildStories[] = isset($relatedStories[$childStoryID]) ? $relatedStories[$childStoryID] : $childStoryID;
}
+1
View File
@@ -2362,6 +2362,7 @@ class storyModel extends model
* Get stories pairs of a product.
*
* @param int $productID
* @param string|int $branch
* @param array|string $moduleIdList
* @param string $status
* @param string $order
+2 -2
View File
@@ -853,7 +853,7 @@ class taskModel extends model
{
$currentTask->status = 'done';
$currentTask->finishedBy = $this->app->user->account;
$currentTask->finishedDate = $now;
$currentTask->finishedDate = $task->finishedDate;
}
}
@@ -1717,7 +1717,7 @@ class taskModel extends model
->setDefault('status', 'done')
->setDefault('finishedBy, lastEditedBy', $this->app->user->account)
->setDefault('finishedDate, lastEditedDate', $now)
->removeIF(!empty($oldTask->team), 'finishedBy,finishedDate,status,left')
->removeIF(!empty($oldTask->team), 'finishedBy,status,left')
->remove('comment,files,labels,currentConsumed')
->get();
+2 -4
View File
@@ -894,20 +894,18 @@ class testcase extends control
{
$branchTagOption[$branchInfo->id] = $branchInfo->name . ($branchInfo->status == 'closed' ? ' (' . $this->lang->branch->statusList['closed'] . ')' : '');
}
$this->view->productID = $productID;
$this->view->product = $product;
$this->view->branchTagOption = $branchTagOption;
$this->view->productName = $this->products[$productID];
$this->view->moduleOptionMenu = $moduleOptionMenu;
$this->view->stories = $this->story->getProductStoryPairs($productID, $case->branch);
$this->view->stories = $this->story->getProductStoryPairs($productID, $case->branch, 0, 'all','id_desc', 0, 'full', 'story', false);
}
$forceNotReview = $this->testcase->forceNotReview();
if($forceNotReview) unset($this->lang->testcase->statusList['wait']);
$position[] = $this->lang->testcase->common;
$position[] = $this->lang->testcase->edit;
$this->view->title = $title;
$this->view->position = $position;
$this->view->currentModuleID = $case->module;
$this->view->users = $this->user->getPairs('noletter');
$this->view->case = $case;
+6 -3
View File
@@ -33,8 +33,11 @@ fields:
format: ""
- field: actor
note: "操作者"
from: common.user.v1.yaml
use: user
fields:
- field: actor1
range: admin,dev,test
- field: actor2
range: [],17-18
prefix: ""
postfix: ""
loop: 0
@@ -62,7 +65,7 @@ fields:
format: ""
- field: extra
note: "附加参数"
range: "0"
range: 1{4},11,1{22},33,1{22},101,1{22},131,1{22},161,1{3}
prefix: ""
postfix: ""
loop: 0
+47
View File
@@ -0,0 +1,47 @@
title: table zt_history
desc: "操作历史"
author: automated export
version: "1.0"
fields:
- field: id
note: "ID"
range: 1-100
prefix: ""
postfix: ""
loop: 0
format: ""
- field: action
note: "关联日志"
range: 1-100
prefix: ""
postfix: ""
loop: 0
format: ""
- field: field
note: "字段"
range: "resolution,resolvedBuild,resolvedDate,status"
prefix: ""
postfix: ""
loop: 0
format: ""
- field: old
note: "旧值"
range: [1,2,2020-01-01,doing]
prefix: ""
postfix: ""
loop: 0
format: ""
- field: new
note: "新值"
range: [2,3,2020-01-17,done]
prefix: ""
postfix: ""
loop: 0
format: ""
- field: diff
note: "不同"
range: ""
prefix: ""
postfix: ""
loop: 0
format: ""
+1
View File
@@ -11,6 +11,7 @@ $builder->usercontact = array('rows' => 61, 'extends' => array('usercontact'));
$builder->userview = array('rows' => 400, 'extends' => array('userview'));
$builder->dept = array('rows' => 100, 'extends' => array('dept'));
$builder->action = array('rows' => 100, 'extends' => array('action'));
$builder->history = array('rows' => 100, 'extends' => array('history'));
$builder->program = array('rows' => 10, 'extends' => array('project', 'program'));
$builder->project = array('rows' => 90, 'extends' => array('project', 'project'));
+2 -1
View File
@@ -20,4 +20,5 @@ $program2 = $tester->program->getById(12);
$result1 = $tester->program->getBudgetLeft($program1);
$result2 = $tester->program->getBudgetLeft($program2);
r($result) && p() && e('0'); // 查看父项目集id=1的预算剩余
r($result) && p() && e('900000'); // 查看项目11的所有父项目集的预算剩余
r($result) && p() && e('899900'); // 查看项目12的所有父项目集的预算剩余
+4 -4
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env php
<?php
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
include dirname(dirname(dirname(__FILE__))) . '/class/program.class.php';
su('admin');
/**
@@ -13,7 +13,7 @@ pid=1
*/
$CurrencyType = new Program('admin');
global $tester;
$tester->loadModel('project');
/* GetBudgetUnitList(). */
r($CurrencyType->getBudgetUnitList()) && p('CNY;USD') && e('人民币;美元'); //获取货币类型列表
r($tester->loadModel('program')->getBudgetUnitList()) && p('CNY;USD') && e('人民币;美元'); //获取货币类型列表
+4 -4
View File
@@ -16,9 +16,9 @@ GetParentPM(). >> 0
global $tester;
$tester->loadModel('program');
$programIdList = array(1, 2, 3);
$programIdList = array(11, 12, 13);
$parentPM = $tester->program->getParentPM($programIdList);
a($parentPM);die;
/* GetParentPM($programIdList). */
r($getPM->getParentPM('1')) && p() && e('0'); //
r(count($parentPM)) && p() && e('2'); // 获取父项目集的负责人数量
r($parentPM) && p('12:pm2') && e('pm2'); // 获取父项目集的负责人account
r($parentPM) && p('13:pm3') && e('pm3'); // 获取父项目集的负责人account
+9 -11
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env php
<?php
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
include dirname(dirname(dirname(__FILE__))) . '/class/program.class.php';
su('admin');
/**
@@ -19,14 +19,12 @@ pid=1
*/
$program = new Program('admin');
global $tester;
$tester->loadModel('program');
$stats1 = $tester->program->getProjectStats(1);
$stats2 = $tester->program->getProjectStats(2, 'undone', 0, 'id_asc', null);
$t_statusNmb = array(0, 'doing', 'name_desc', 'id_desc', 0, 1 ,1, 'count');
r($program->getStatsByProgramID($t_statusNmb[0])) && p() && e('68'); // 查看当前项目集下所有未开始和进行中的项目的个数
r($program->getStatsByStatus($t_statusNmb[1])) && p() && e('44'); // 查看当前项目集下所有状态为进行中的项目的个数
r($program->getStatsByOrder($t_statusNmb[2])) && p() && e('1'); // 根据name倒序查看所有项目
r($program->getStatsByOrder($t_statusNmb[3])) && p() && e('1'); // 根据id倒序查看所有项目的个数
r($program->getStatsAddProgramTitle($t_statusNmb[4])) && p('11:name') && e('项目1'); // 查看所有项目(包含所属项目集名称)
r($program->getStatsByInvolved($t_statusNmb[5])) && p('11:name') && e('项目1'); // 查看当前用户参与的项目
r($program->getStatsByInvolved($t_statusNmb[6], $t_statusNmb[7])) && p() && e('1'); // 查看当前用户参与的项目的个数
r(count($stats1)) && p() && e('7'); // 查看当前项目集下所有未完成的项目的个数
r(count($stats2)) && p() && e('7'); // 查看当前项目集下所有未完成的项目的个数
r(current($stats1)) && p('id,name') && e('91,项目81'); // 查看当前项目集下所有未完成的项目按照id倒序排的第一个项目集信息
r(current($stats2)) && p('id,name') && e('12,项目2'); // 查看当前项目集下所有未完成的项目按照id正序排的第一个项目集信息
+9 -7
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env php
<?php
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
include dirname(dirname(dirname(__FILE__))) . '/class/program.class.php';
su('admin');
/**
@@ -14,10 +14,12 @@ pid=1
*/
$program = new Program('admin');
global $tester;
$tester->loadModel('program');
$teams1 = $tester->program->getTeamMemberPairs(1);
$teams2 = $tester->program->getTeamMemberPairs(2);
$t_Tnumber = array(1);
//var_dump($program->getById2($t_Tnumber[0]));die;
r($program->getById2($t_Tnumber[0])) && p('pm92') && e('P:产品经理92'); //获取项目集下所有团队成员
r($program->getCount6($t_Tnumber[0])) && p() && e('19'); // 获取项目集下所有团队成员
r(count($teams1)) && p() && e('19'); // 获取项目集1下所有团队成员数量
r(count($teams2)) && p() && e('19'); // 获取项目集2下所有团队成员数量
r($teams1) && p('pm92') && e('P:产品经理92'); // 获取项目集1下所有团队成员真实姓名
r($teams2) && p('user83') && e('U:测试83'); // 获取项目集2下所有团队成员真实姓名
+5 -5
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long