This commit is contained in:
Yagami
2020-08-24 11:45:10 +08:00
9 changed files with 75 additions and 39 deletions

View File

@@ -1598,7 +1598,7 @@ class block extends control
->leftJoin(TABLE_PROJECT)->alias('t4')->on('t1.project=t4.id')
->leftJoin(TABLE_PROJECTPRODUCT)->alias('t5')->on('t1.project=t5.project')
->where('t1.deleted')->eq('0')
->andWhere('t1.product')->eq($this->session->program)->fi()
->andWhere('t1.program')->eq($this->session->program)->fi()
->andWhere('t1.product = t5.product')
->beginIF($this->params->type != 'all')->andWhere('t1.status')->eq($this->params->type)->fi()
->orderBy('t1.id desc')
@@ -1625,7 +1625,7 @@ class block extends control
*/
public function printScrumprojectBlock()
{
$this->view->projectOverview = $this->dao->select('count(*) total, count(if(status="doing", id, null)) as doing, count(if(status="closed", id, null)) as finish')->from(TABLE_PROJECT)
$this->view->summary = $this->dao->select('count(*) as total, count(if(status="doing", id, null)) as doing, count(if(status="closed", id, null)) as finish')->from(TABLE_PROJECT)
->where('program')->eq($this->session->program)
->fetch();
}
@@ -1638,13 +1638,27 @@ class block extends control
*/
public function printScrumdynamicBlock()
{
$projects = $this->loadModel('project')->getPairs();
$actions = $this->dao->select('*')->from(TABLE_ACTION)
->where('project')->in(array_keys($projects))
->orderBy('id_desc')
->fetchAll();
$projects = $this->loadModel('project')->getPairs();
$products = $this->loadModel('product')->getPairs();
$productID = array();
foreach($products as $id => $name) $productID[] = ',' . $id . ',';
$this->view->actions = $this->loadModel('action')->transformActions($actions);
if(empty($projects) && empty($products))
{
$actions = array();
}
else
{
$actions = $this->dao->select('*')->from(TABLE_ACTION)
->beginIF($projects && $products)->where('project')->in(array_keys($projects))->orWhere('product')->in($productID)->fi()
->beginIF($projects && empty($products))->where('project')->in(array_keys($projects))->fi()
->beginIF(empty($projects) && $products)->where('product')->in($productID)->fi()
->orderBy('id_desc')
->limit(30)
->fetchAll();
}
$this->view->actions = empty($actions) ? array() : $this->loadModel('action')->transformActions($actions);
$this->view->users = $this->loadModel('user')->getPairs('noletter');
}
}
}

View File

@@ -53,6 +53,9 @@ $lang->block->resolvedBugs = '解决Bug数';
$lang->block->openedTestcases = '创建用例数';
$lang->block->cmmi = 'CMMI 3';
$lang->block->scrum = 'Scrum+';
$lang->block->allProject = '所有' . $lang->projectCommon;
$lang->block->doingProject = '进行中的' . $lang->projectCommon;
$lang->block->finishProject = '累积' . $lang->projectCommon;
$lang->block->params = new stdclass();
$lang->block->params->name = '参数名称';
@@ -109,15 +112,15 @@ $lang->block->default['cmmi']['program']['7']['params']['type'] = 'all';
$lang->block->default['cmmi']['program']['7']['params']['num'] = '15';
$lang->block->default['cmmi']['program']['7']['params']['orderBy'] = 'id_desc';
$lang->block->default['scrum']['program']['1']['title'] = '项目整体情况';
$lang->block->default['scrum']['program']['1']['title'] = '项目整体情况';
$lang->block->default['scrum']['program']['1']['block'] = 'scrumoverall';
$lang->block->default['scrum']['program']['1']['grid'] = 8;
$lang->block->default['scrum']['program']['2']['title'] = '进行中的迭代';
$lang->block->default['scrum']['program']['2']['title'] = '进行中的' . $lang->projectCommon;
$lang->block->default['scrum']['program']['2']['block'] = 'scrumprogress';
$lang->block->default['scrum']['program']['2']['grid'] = 8;
$lang->block->default['scrum']['program']['3']['title'] = '产品路线图';
$lang->block->default['scrum']['program']['3']['title'] = $lang->productCommon . '路线图';
$lang->block->default['scrum']['program']['3']['block'] = 'scrumroadmap';
$lang->block->default['scrum']['program']['3']['grid'] = 8;
@@ -129,11 +132,11 @@ $lang->block->default['scrum']['program']['4']['params']['type'] = 'all';
$lang->block->default['scrum']['program']['4']['params']['num'] = '15';
$lang->block->default['scrum']['program']['4']['params']['orderBy'] = 'id_desc';
$lang->block->default['scrum']['program']['5']['title'] = '产品总览';
$lang->block->default['scrum']['program']['5']['title'] = $lang->productCommon . '总览';
$lang->block->default['scrum']['program']['5']['block'] = 'scrumproduct';
$lang->block->default['scrum']['program']['5']['grid'] = 4;
$lang->block->default['scrum']['program']['6']['title'] = '迭代总览';
$lang->block->default['scrum']['program']['6']['title'] = $lang->projectCommon . '总览';
$lang->block->default['scrum']['program']['6']['block'] = 'scrumproject';
$lang->block->default['scrum']['program']['6']['grid'] = 4;
@@ -310,11 +313,11 @@ $lang->block->modules['program']->availableBlocks->list = '项目列表
$lang->block->modules['scrum']['index'] = new stdclass();
$lang->block->modules['scrum']['index']->availableBlocks = new stdclass();
$lang->block->modules['scrum']['index']->availableBlocks->scrumoverall = '项目整体情况';
$lang->block->modules['scrum']['index']->availableBlocks->scrumprogress = '进行中的迭代';
$lang->block->modules['scrum']['index']->availableBlocks->scrumproject = '迭代总览';
$lang->block->modules['scrum']['index']->availableBlocks->scrumproduct = '产品总览';
$lang->block->modules['scrum']['index']->availableBlocks->scrumprogress = '进行中的' . $lang->projectCommon;
$lang->block->modules['scrum']['index']->availableBlocks->scrumproject = $lang->projectCommon . '总览';
$lang->block->modules['scrum']['index']->availableBlocks->scrumproduct = $lang->productCommon . '总览';
$lang->block->modules['scrum']['index']->availableBlocks->scrumtest = '待测版本';
$lang->block->modules['scrum']['index']->availableBlocks->scrumroadmap = '产品路线图';
$lang->block->modules['scrum']['index']->availableBlocks->scrumroadmap = $lang->productCommon . '路线图';
$lang->block->modules['cmmi']['index'] = new stdclass();
$lang->block->modules['cmmi']['index']->availableBlocks = new stdclass();

View File

@@ -1,10 +1,6 @@
<?php if(empty($actions)): ?>
<div class='empty-tip'><?php echo $lang->block->emptyTip;?></div>
<?php else:?>
<style>
.block-dynamic .timeline > li .timeline-text {display: block; overflow: hidden; text-overflow: ellipsis; max-height: 20px; display: -webkit-box; -webkit-line-clamp: 1; -webkit-box-orient: vertical; }
.block-dynamic .panel-body {padding-top: 0;}
</style>
<div class='panel-body scrollbar-hover'>
<ul class="timeline timeline-tag-left no-margin">
<?php

View File

@@ -10,7 +10,7 @@
* @link http://www.zentao.net
*/
?>
<?php if(empty($projectOverview)): ?>
<?php if(empty($summary)): ?>
<div class='empty-tip'><?php echo $lang->block->emptyTip;?></div>
<?php else:?>
<style>
@@ -27,19 +27,19 @@
<div class="panel-body table-row">
<div class="col-4 text-middle text-center">
<div class="tile">
<div class="tile-title">所有阶段</div>
<div class="tile-amount">25</div>
<div class="tile-title"><?php echo $lang->block->allProject;?></div>
<div class="tile-amount"><?php echo $summary->total;?></div>
</div>
</div>
<div class="col-8 text-middle">
<ul class="status-bars" style="transform: rotate(90deg);">
<ul class="status-bars all-statistics">
<li>
<span class="bar" style="height: 0%"><span class="value">0</span></span>
<span class="title">进行中</span>
<span class="bar" style="height: <?php echo empty($summary->doing) ? 0 : round(($summary->doing/$summary->total) * 100);?>%"><span class="value"><?php echo $summary->doing;?></span></span>
<span class="title"><?php echo $lang->block->doingProject;?></span>
</li>
<li>
<span class="bar" style="height: 100%"><span class="value">100</span></span>
<span class="title">已挂起</span>
<span class="bar" style="height: <?php echo empty($summary->finish) ? 0 : round(($summary->finish/$summary->total) * 100);?>%"><span class="value"><?php echo $summary->finish;?></span></span>
<span class="title"><?php echo $lang->block->finishProject;?></span>
</li>
</ul>
</div>

View File

@@ -935,11 +935,12 @@ class project extends control
* @access public
* @return void
*/
public function burn($projectID = 0, $type = 'noweekend', $interval = 0)
public function burn($projectID = 0, $type = 'noweekend', $interval = 0, $burnBy = 'left')
{
$this->loadModel('report');
$project = $this->commonAction($projectID);
$projectID = $project->id;
$burnBy = $this->cookie->burnBy ? $this->cookie->burnBy : $burnBy;
/* Header and position. */
$title = $project->name . $this->lang->colon . $this->lang->project->burn;
@@ -949,7 +950,7 @@ class project extends control
/* Get date list. */
$projectInfo = $this->project->getByID($projectID);
list($dateList, $interval) = $this->project->getDateList($projectInfo->begin, $projectInfo->end, $type, $interval, 'Y-m-d');
$chartData = $this->project->buildBurnData($projectID, $dateList, $type);
$chartData = $this->project->buildBurnData($projectID, $dateList, $type, $burnBy);
$dayList = array_fill(1, floor($project->days / $this->config->project->maxBurnDay) + 5, '');
foreach($dayList as $key => $val) $dayList[$key] = $this->lang->project->interval . ($key + 1) . $this->lang->day;
@@ -958,6 +959,7 @@ class project extends control
$this->view->title = $title;
$this->view->position = $position;
$this->view->tabID = 'burn';
$this->view->burnBy = $burnBy;
$this->view->projectID = $projectID;
$this->view->projectName = $project->name;
$this->view->type = $type;

View File

@@ -5,3 +5,5 @@
#burnLegend > div {position: relative; padding-left: 30px;}
#burnLegend > div > .barline {position: absolute; width: 20px; left: 0; top: 13px; height: 3px; background: #EEEEEE;}
#burnLegend .line-real .bg-primary{background: #1183fb}
.pull-left .input-control{margin-right: 10px}

View File

@@ -117,6 +117,12 @@ $lang->project->aclList['open'] = "默认设置(有{$lang->projectCommon}视
$lang->project->aclList['private'] = "私有{$lang->projectCommon}(只有{$lang->projectCommon}团队成员才能访问)";
$lang->project->aclList['custom'] = "自定义白名单(团队成员和白名单的成员可以访问)";
$lang->project->storyPoint = '故事点';
$lang->project->burnByList['left'] = '按剩余工时查看';
$lang->project->burnByList['estimate'] = '按计划工时查看';
$lang->project->burnByList['storyPoint'] = '按故事点查看';
/* 方法列表。*/
$lang->project->index = "{$lang->projectCommon}主页";
$lang->project->task = '任务列表';

View File

@@ -2013,16 +2013,17 @@ class projectModel extends model
* Get burn data for flot
*
* @param int $projectID
* @param string $burnBy
* @access public
* @return array
*/
public function getBurnDataFlot($projectID = 0)
public function getBurnDataFlot($projectID = 0, $burnBy = '')
{
/* Get project and burn counts. */
$project = $this->getById($projectID);
/* If the burnCounts > $itemCounts, get the latest $itemCounts records. */
$sets = $this->dao->select('date AS name, `left` AS value, estimate')->from(TABLE_BURN)->where('project')->eq((int)$projectID)->andWhere('task')->eq(0)->orderBy('date DESC')->fetchAll('name');
$sets = $this->dao->select("date AS name, `left` AS value, `$burnBy`")->from(TABLE_BURN)->where('project')->eq((int)$projectID)->andWhere('task')->eq(0)->orderBy('date DESC')->fetchAll('name');
$count = 0;
$burnData = array();
@@ -2757,19 +2758,21 @@ class projectModel extends model
* @param int $projectID
* @param array $dateList
* @param string $type
* @param string $burnBy
* @access public
* @return array
*/
public function buildBurnData($projectID, $dateList, $type)
public function buildBurnData($projectID, $dateList, $type, $burnBy = 'left')
{
$this->loadModel('report');
$burnBy = $burnBy ? $burnBy : 'left';
$sets = $this->getBurnDataFlot($projectID);
$sets = $this->getBurnDataFlot($projectID, $burnBy);
$limitJSON = '[]';
$baselineJSON = '[]';
$firstBurn = empty($sets) ? 0 : reset($sets);
$firstTime = !empty($firstBurn->estimate) ? $firstBurn->estimate : (!empty($firstBurn->value) ? $firstBurn->value : 0);
$firstTime = !empty($firstBurn->$burnBy) ? $firstBurn->$burnBy : (!empty($firstBurn->value) ? $firstBurn->value : 0);
$days = count($dateList) - 1;
$rate = $firstTime / $days;
$baselineJSON = '[';

View File

@@ -26,6 +26,9 @@
common::printLink('project', 'fixFirst', "project=$project->id", $lang->project->fixFirst, '', "class='btn btn-link iframe' data-width='700'");
echo $lang->project->howToUpdateBurn;
?>
<div class='input-control w-150px'>
<?php echo html::select('burnBy', $lang->project->burnByList, $burnBy, "class='form-control chosen'");?>
</div>
<?php if($interval):?>
<div class='input-control thWidth'>
<?php echo html::select('interval', $dayList, $interval, "class='form-control chosen'");?>
@@ -37,12 +40,12 @@
</div>
</div>
<div id='mainContent' class='main-content'>
<h2 class='text-center'><?php echo $projectName . ' ' . $this->lang->project->burn;?></h2>
<h2 class='text-center'><?php echo $projectName . ' ' . $this->lang->project->burn . '(' . zget($lang->project->burnByList, $burnBy) . ')';?></h2>
<div id="burnWrapper">
<div id="burnChart">
<canvas id="burnCanvas"></canvas>
</div>
<div id="burnYUnit"><?php echo "({$lang->project->workHour})";?></div>
<div id="burnYUnit"><?php echo $burnBy == 'storyPoint' ? "({$lang->project->storyPoint})" : "({$lang->project->workHour})";?></div>
<div id="burnLegend">
<div class="line-ref"><div class='barline'></div><?php echo $lang->project->charts->burn->graph->reference;?></div>
<div class="line-real"><div class='barline bg-primary'></div><?php echo $lang->project->charts->burn->graph->actuality;?></div>
@@ -50,6 +53,13 @@
</div>
</div>
<script>
$('#burnBy').change(function()
{
$.cookie('burnBy', $(this).val(), {expires:config.cookieLife, path:config.webRoot});
var interval = typeof($('#interval').val()) == 'undefined' ? 0 : $('#interval').val() ;
location.href = createLink('project', 'burn', 'projectID=' + projectID + '&type=' + type + '&interval=' + interval + '&burnBy=' + $(this).val());
});
function initBurnChar()
{
var themePrimaryColor = $.getThemeColor('primary');