Merge branch 'master' of https://gitlab.zcorp.cc/easycorp/zentaopms into zentaopms_289

This commit is contained in:
caoyanyi
2023-03-01 11:52:44 +08:00
16 changed files with 52 additions and 139 deletions
+5 -3
View File
@@ -418,9 +418,11 @@ $config->pipelineTypeList = array('gitlab', 'gogs', 'gitea', 'jenkins', 'sonarqu
/* Program privs.*/
$config->programPriv = new stdclass();
$config->programPriv->noSprint = array('task', 'story', 'tree', 'project', 'execution', 'build', 'bug', 'testcase', 'testreport', 'doc', 'repo', 'stakeholder', 'projectrelease', 'requirement');
$config->programPriv->scrum = array('story', 'requirement', 'productplan', 'tree', 'projectplan', 'projectstory', 'projectrelease', 'project', 'execution', 'build', 'bug', 'testcase', 'testreport', 'doc', 'repo', 'meeting', 'stakeholder', 'testtask');
$config->programPriv->waterfall = array_merge($config->programPriv->scrum, array('workestimation', 'durationestimation', 'budget', 'programplan', 'review', 'reviewissue', 'weekly', 'cm', 'milestone', 'design', 'issue', 'risk', 'opportunity', 'measrecord', 'auditplan', 'trainplan', 'gapanalysis', 'pssp', 'researchplan', 'researchreport'));
$config->programPriv->noSprint = array('task', 'story', 'tree', 'project', 'execution', 'build', 'bug', 'testcase', 'testreport', 'doc', 'repo', 'stakeholder', 'projectrelease', 'requirement');
$config->programPriv->scrum = array('story', 'requirement', 'productplan', 'tree', 'projectplan', 'projectstory', 'projectrelease', 'project', 'execution', 'build', 'bug', 'testcase', 'testreport', 'doc', 'repo', 'meeting', 'stakeholder', 'testtask');
$config->programPriv->waterfall = array_merge($config->programPriv->scrum, array('workestimation', 'durationestimation', 'budget', 'programplan', 'review', 'reviewissue', 'weekly', 'cm', 'milestone', 'design', 'issue', 'risk', 'opportunity', 'measrecord', 'auditplan', 'trainplan', 'gapanalysis', 'pssp', 'researchplan', 'researchreport'));
$config->programPriv->agileplus = $config->programPriv->scrum;
$config->programPriv->waterfallplus = $config->programPriv->waterfall;
$config->waterfallModules = array('workestimation', 'durationestimation', 'budget', 'programplan', 'review', 'reviewissue', 'weekly', 'cm', 'milestone', 'design', 'opportunity', 'auditplan', 'trainplan', 'gapanalysis', 'pssp', 'researchplan', 'researchreport');
+2
View File
@@ -260,5 +260,7 @@ INSERT IGNORE INTO `zt_lang` (`lang`, `module`, `section`, `key`, `value`, `syst
UPDATE `zt_grouppriv` SET `module` = 'testcase' WHERE `module` = 'story' and `method` = 'zeroCase';
UPDATE `zt_grouppriv` SET `module` = 'product' WHERE `module` = 'story' and `method` = 'track';
REPLACE INTO `zt_grouppriv` (`group`, `module`, `method`) SELECT `group`, 'product', 'requirement' FROM `zt_grouppriv` WHERE `module` = 'product' AND `method` = 'browse';
ALTER TABLE `zt_job` ADD `lastSyncDate` datetime DEFAULT NULL AFTER `lastTag`;
INSERT INTO `zt_cron` (`m`, `h`, `dom`, `mon`, `dow`, `command`, `remark`, `type`, `buildin`, `status`, `lastTime`) VALUES ('*/5', '*', '*', '*', '*', 'moduleName=compile&methodName=syncCompile', '定时同步构建记录', 'zentao', 1, 'normal', '0000-00-00 00:00:00');
+19
View File
@@ -11,6 +11,25 @@
*/
class admin extends control
{
/**
* The gogs constructor.
* @param string $moduleName
* @param string $methodName
*/
public function __construct($moduleName = '', $methodName = '')
{
parent::__construct($moduleName, $methodName);
if(!isset($this->config->global->sn))
{
$this->loadModel('setting');
$this->setting->setItem('system.common.global.sn', $this->setting->computeSN());
if(!isset($this->config->global)) $this->config->global = new stdclass();
$this->config->global->sn = $this->setting->getItem('owner=system&module=common&section=global&key=sn');
}
}
/**
* Index page.
* @access public
+1 -1
View File
@@ -62,7 +62,7 @@
.official {justify-content: center;}
.official > .panel-title {position: absolute; top: 0px;}
.official-img {background-image: url('/static/images/wechat.jpg'); background-repeat: no-repeat; background-size: contain; flex: 1 1 30%; aspect-ratio: 1 / 1; background-position: center;}
.official-img {background-image: url('static/images/wechat.jpg'); background-repeat: no-repeat; background-size: contain; flex: 1 1 30%; aspect-ratio: 1 / 1; background-position: center;}
.official-content {flex: 0 0 60%; display: flex; flex-direction: column; padding-left: 10px; padding-top: 15px;}
.official-content > .content {color: #838A9D; font-size: 12px; line-height: 22px; padding-top: 6px;}
.official-content > .title {color: #313C52; font-size: 13px; line-height: 14px;}
+1 -1
View File
@@ -85,7 +85,7 @@ $lang->admin->menuList->model['menuOrder']['20'] = 'agileplus';
$lang->admin->menuList->model['menuOrder']['25'] = 'waterfallplus';
$lang->admin->menuList->model['tabMenu']['common']['project'] = array('link' => "{$lang->project->common}|custom|required|module=project", 'alias' => 'set', 'exclude' => 'custom', 'links' => array('custom|set|module=project&field=unitList'));
if(helper::hasFeature('waterfall') or helper::hasFeature('waterfallplus')) $lang->admin->menuList->model['tabMenu']['common']['stage'] = array('link' => "{$lang->stage->type}|stage|settype|", 'subModule' => 'stage', 'links' => array('stage|browse|'));
if(helper::hasFeature('waterfall') or helper::hasFeature('waterfallplus')) $lang->admin->menuList->model['tabMenu']['common']['stage'] = array('link' => "{$lang->stage->type}|stage|settype|", 'subModule' => 'stage');
$lang->admin->menuList->model['tabMenu']['common']['build'] = array('link' => "{$lang->build->common}|custom|required|module=build", 'alias' => 'set', 'exclude' => 'custom');
$lang->admin->menuList->model['tabMenu']['common']['flow'] = array('link' => "{$lang->custom->flow}|custom|flow|", 'divider' => true);
$lang->admin->menuList->model['tabMenu']['common']['code'] = array('link' => "{$lang->code}|custom|code|");
+3 -3
View File
@@ -23,7 +23,7 @@
<button class="btn shadow-primary-hover" <?php if($menu['disabled']) echo 'disabled';?> data-link='<?php echo $menu['link'];?>'>
<h4 class="flex align-center w-full">
<div class="flex align-center">
<img src="/static/svg/admin-<?php echo $menuKey;?>.svg"/>
<img src="static/svg/admin-<?php echo $menuKey;?>.svg"/>
<?php echo $menu['name'];?>
</div>
<?php echo html::a($config->admin->helpURL[$menuKey], "<i class='icon icon-help'></i> ", '_blank', 'class="text-muted setting-help"');?>
@@ -45,7 +45,7 @@
<?php foreach($plugins as $plugin):?>
<?php $pluginDesc = preg_replace('/[[:cntrl:]]/mu', '', strip_tags($plugin->abstract));?>
<div class="plugin-item shadow-primary-hover" data-link='<?php echo $plugin->viewLink;?>'>
<a href="<?php echo $plugin->viewLink;?>" class='ext-download' target='_blank'><i class='icon icon-download-alt text-primary bg-primary-100 pd-3'></i></a>
<span class='ext-download'><i class='icon icon-download-alt text-primary bg-primary-100 pd-3'></i></span>
<h4 class="plug-title" title="<?php echo $plugin->name;?>"><?php echo $plugin->name;?></h4>
<p class='extension-desc text-muted' title="<?php echo $pluginDesc;?>"><?php echo $pluginDesc;?></p>
</div>
@@ -70,7 +70,7 @@
<div class="content"> <?php echo $lang->admin->followUsContent?></div>
</div>
</div>
<?php if(!$bind and !$ignore and common::hasPriv('admin', 'register')):?>
<?php if(!$bind and !$ignore and $hasInternet and common::hasPriv('admin', 'register')):?>
<div class="panel-link"> <?php echo sprintf($lang->admin->notice->register, html::a(inlink('register'), $lang->admin->registerNotice->submitHere, '', 'class="text-primary"'));?></div>
<?php endif;?>
</div>
+1 -1
View File
@@ -266,7 +266,7 @@ $lang->custom->features['qa'] = 'QA';
$lang->custom->features['devops'] = 'DevOps';
$lang->custom->features['kanban'] = 'Kanban';
$lang->custom->features['doc'] = 'Doc';
$lang->custom->features['report'] = 'Statistics';
$lang->custom->features['report'] = $lang->report->common;
$lang->custom->features['system'] = 'System';
$lang->custom->features['assetlib'] = 'Asset Lib';
$lang->custom->features['oa'] = 'Attend';
+1 -1
View File
@@ -266,7 +266,7 @@ $lang->custom->features['qa'] = 'QA';
$lang->custom->features['devops'] = 'DevOps';
$lang->custom->features['kanban'] = 'Kanban';
$lang->custom->features['doc'] = 'Doc';
$lang->custom->features['report'] = 'Statistics';
$lang->custom->features['report'] = $lang->report->common;
$lang->custom->features['system'] = 'System';
$lang->custom->features['assetlib'] = 'Asset Lib';
$lang->custom->features['oa'] = 'Attend';
+1 -1
View File
@@ -266,7 +266,7 @@ $lang->custom->features['qa'] = 'QA';
$lang->custom->features['devops'] = 'DevOps';
$lang->custom->features['kanban'] = 'Kanban';
$lang->custom->features['doc'] = 'Doc';
$lang->custom->features['report'] = 'Statistics';
$lang->custom->features['report'] = $lang->report->common;
$lang->custom->features['system'] = 'System';
$lang->custom->features['assetlib'] = 'Asset Lib';
$lang->custom->features['oa'] = 'Attend';
+1 -1
View File
@@ -266,7 +266,7 @@ $lang->custom->features['qa'] = '测试';
$lang->custom->features['devops'] = 'DevOps';
$lang->custom->features['kanban'] = '看板';
$lang->custom->features['doc'] = '文档';
$lang->custom->features['report'] = '统计';
$lang->custom->features['report'] = $lang->report->common;
$lang->custom->features['system'] = '组织';
$lang->custom->features['assetlib'] = '资产库';
$lang->custom->features['oa'] = '办公';
+5 -89
View File
@@ -1091,46 +1091,8 @@ class executionModel extends model
$this->action->logHistory($actionID, $changes);
/* This stage has a parent stage. */
$checkTopStage = $this->programplan->checkTopStage($executionID);
$siblingsAllWait = true;
if(!$checkTopStage)
{
/* Check sibling stages are all wait. */
foreach($siblingStages as $siblingID => $sibling)
{
if($siblingID == $executionID) continue;
if($sibling->status != 'wait')
{
$siblingsAllWait = false;
break;
}
}
if($siblingsAllWait)
{
/* Actual start or consumed work exists for the parent phase. */
$parent = $this->dao->select('*')->from(TABLE_EXECUTION)->where('id')->eq($parentID)->fetch();
$parentsChildren = $this->dao->select('id')->from(TABLE_EXECUTION)->where('deleted')->eq(0)->andWhere('path')->like("%,$executionID,%")->andWhere('id')->ne($parentID)->fetchPairs();
$parentHasConsumedTasks = $this->dao->select('count(id) as count')->from(TABLE_TASK)->where('deleted')->eq(0)->andWhere('execution')->in($parentsChildren)->andWhere('consumed')->gt(0)->fetch('count');
$parentStatus = (!helper::isZeroDate($parent->realBegan) or $parentHasConsumedTasks) ? 'doing' : 'wait';
if($parent->status == $parentStatus) return '';
$newParent = $this->buildExecutionByStatus($parentStatus);
$this->dao->update(TABLE_EXECUTION)->data($newParent)->where('id')->eq($parentID)->exec();
if(!dao::isError())
{
$changes = common::createChanges($parent, $newParent);
$actionType = $parentStatus == 'doing' ? 'started' : 'waitbychild';
$actionID = $this->action->create('execution', $parentID, $actionType, '', $actionType);
$this->action->logHistory($actionID, $changes);
if($parent->status == 'wait' and $parentStatus == 'doing') $this->loadModel('common')->syncPPEStatus($parentID);
}
}
}
$checkTopStage = $this->programplan->checkTopStage($executionID);
if(!$checkTopStage) $this->programplan->computeProgress($executionID);
}
}
@@ -1162,23 +1124,7 @@ class executionModel extends model
/* This stage has a parent stage. */
$checkTopStage = $this->programplan->checkTopStage($executionID);
if(!$checkTopStage)
{
$parent = $this->dao->select('*')->from(TABLE_EXECUTION)->where('id')->eq($parentID)->fetch();
if($parent->status == 'doing') return '';
$newParent = $this->buildExecutionByStatus('doing');
$this->dao->update(TABLE_EXECUTION)->data($newParent)->where('id')->eq($parentID)->exec();
if(!dao::isError())
{
$changes = common::createChanges($parent, $newParent);
$actionID = $this->action->create('execution', $parentID, 'startbychildedit', '', 'startbychildedit');
$this->action->logHistory($actionID, $changes);
if($parent->status == 'wait') $this->loadModel('common')->syncPPEStatus($parentID);
}
}
if(!$checkTopStage) $this->programplan->computeProgress($executionID);
}
}
@@ -1226,38 +1172,8 @@ class executionModel extends model
/* Suspended: When all child stages at the same level are suspended or closed, the status of the parent stage becomes "suspended". */
/* Closed: When all child stages at the same level are closed, the status of the parent stage becomes "closed". */
$checkTopStage = $this->programplan->checkTopStage($executionID);
$siblingsAllInactived = true;
if(!$checkTopStage)
{
foreach($siblingStages as $siblingID => $sibling)
{
if($siblingID == $executionID) continue;
if(strpos($checkedStatus, $sibling->status) !== false)
{
$siblingsAllInactived = false;
break;
}
}
if($siblingsAllInactived)
{
$parent = $this->dao->select('*')->from(TABLE_EXECUTION)->where('id')->eq($parentID)->fetch();
if($parent->status == $status) return '';
$newParent = $this->buildExecutionByStatus($status);
$this->dao->update(TABLE_EXECUTION)->data($newParent)->where('id')->eq($parentID)->exec();
if(!dao::isError())
{
$changes = common::createChanges($parent, $newParent);
$actionType = $status == 'suspended' ? 'suspendbychild' : 'closebychild';
$actionID = $this->action->create('execution', $parentID, $actionType, '', $actionType);
$this->action->logHistory($actionID, $changes);
}
}
}
$checkTopStage = $this->programplan->checkTopStage($executionID);
if(!$checkTopStage) $this->programplan->computeProgress($executionID);
}
}
@@ -11,6 +11,9 @@
*/
?>
<?php include '../../common/view/header.html.php';?>
<?php if(isonlybody()):?>
<style>#importTaskForm .table-footer .pager {z-index: 105;}</style>
<?php endif;?>
<?php js::set('isonlybody', isonlybody());?>
<div id='mainMenu' class='clearfix'>
<div class='pull-left btn-toolbar'>
+4 -31
View File
@@ -1511,16 +1511,7 @@ class programplanModel extends model
{
if($parent->status != 'wait')
{
$newParent = new stdclass();
$newParent->status = 'wait';
$newParent->realBegan = '';
$newParent->closedDate = '';
$newParent->closedBy = '';
$newParent->canceledDate = '';
$newParent->canceledBy = '';
$newParent->suspendedDate = '';
$newParent->lastEditedBy = $this->app->user->account;
$newParent->lastEditedDate = helper::now();
$newParent = $this->execution->buildExecutionByStatus('wait');
$parentAction = 'waitbychild';
}
}
@@ -1528,12 +1519,7 @@ class programplanModel extends model
{
if($parent->status != 'closed')
{
$newParent = new stdclass();
$newParent->status = 'closed';
$newParent->closedDate = helper::now();
$newParent->closedBy = $this->app->user->account;
$newParent->lastEditedBy = $this->app->user->account;
$newParent->lastEditedDate = helper::now();
$newParent = $this->execution->buildExecutionByStatus('closed');
$parentAction = 'closedbychild';
}
}
@@ -1541,11 +1527,7 @@ class programplanModel extends model
{
if($parent->status != 'suspended')
{
$newParent = new stdclass();
$newParent->status = 'suspended';
$newParent->suspendedDate = helper::now();
$newParent->lastEditedBy = $this->app->user->account;
$newParent->lastEditedDate = helper::now();
$newParent = $this->execution->buildExecutionByStatus('suspended');
$parentAction = 'suspendedbychild';
}
}
@@ -1553,16 +1535,7 @@ class programplanModel extends model
{
if($parent->status != 'doing')
{
$newParent = new stdclass();
$newParent->status = 'doing';
$newParent->realBegan = helper::today();
$newParent->closedDate = '';
$newParent->closedBy = '';
$newParent->canceledDate = '';
$newParent->canceledBy = '';
$newParent->suspendedDate = '';
$newParent->lastEditedBy = $this->app->user->account;
$newParent->lastEditedDate = helper::now();
$newParent = $this->execution->buildExecutionByStatus('doing');
$parentAction = $parent->status == 'wait' ?'startbychildstart' : 'startbychild' . $action;
}
}
+3
View File
@@ -414,6 +414,9 @@ function toggleSelectTestStory()
$('.colorpicker').css('right', '0');
$('#dataform .table-form>tbody>tr>th').css('width', '130px');
$('[lang^="zh-"] #dataform .table-form>tbody>tr>th').css('width', '120px');
$('[name^=multiple]').attr('checked', false);
showTeamMenu();
}
else
{
+1 -6
View File
@@ -361,12 +361,7 @@ $(function()
{
var menuModule = task.nav.menuModule || task.nav['module'];
var $navbar = $$('#navbar');
var adminMenu = false;
if(!$navbar.find('li').length)
{
adminMenu = true;
$navbar = $$('.settings-list');
}
if(task.nav.app == 'admin') $navbar = $$('.settings-list');
var $navbarItem = $navbar.find('[data-id="' + menuModule + '"]');
var targetPageTip = lang.targetPageTip.replace('%s', task.nav.targetPageName || lang.target);
if($navbarItem.length && !$navbarItem.hasClass('active'))
+1 -1
View File
@@ -8184,7 +8184,7 @@ class upgradeModel extends model
->fetchAll();
foreach($typeList as $type)
{
$langFile = $this->app->getModuleRoot() . DS . 'stage' . DS . 'lang' . DS . $type->lang . '.php';
$langFile = $this->app->getModuleRoot() . DS . 'stage' . DS . 'lang' . DS . ($type->lang == 'all' ? $this->app->clientLang : $type->lang) . '.php';
if(is_file($langFile)) include $langFile;
$this->dao->replace(TABLE_LANG)