* Finish task #7117/7125/7124.

This commit is contained in:
Yagami
2020-05-06 15:42:56 +08:00
parent 1c5a2dde2c
commit ef44299d7e
11 changed files with 268 additions and 55 deletions

View File

@@ -34,6 +34,7 @@ $filter->qa = new stdclass();
$filter->story = new stdclass();
$filter->task = new stdclass();
$filter->testcase = new stdclass();
$filter->program = new stdclass();
$filter->project = new stdclass();
$filter->testreport = new stdclass();
$filter->testsuite = new stdclass();
@@ -68,6 +69,7 @@ $filter->file->download = new stdclass();
$filter->product->browse = new stdclass();
$filter->product->default = new stdclass();
$filter->product->index = new stdclass();
$filter->program->default = new stdclass();
$filter->project->default = new stdclass();
$filter->project->story = new stdclass();
$filter->project->task = new stdclass();
@@ -128,6 +130,8 @@ $filter->product->default->cookie['preProductID'] = 'int';
$filter->product->index->cookie['preBranch'] = 'int';
$filter->product->export->cookie['checkedItem'] = 'reg::checked';
$filter->program->index->cookie['programType'] = 'code';
$filter->project->default->cookie['lastProject'] = 'int';
$filter->project->default->cookie['projectMode'] = 'code';
$filter->project->story->cookie['storyModuleParam'] = 'int';

View File

@@ -1,5 +1,6 @@
ALTER TABLE `zt_project`
CHANGE `type` `type` varchar(20) COLLATE 'utf8_general_ci' NOT NULL DEFAULT 'waterfall' AFTER `catID`,
ADD `program` mediumint(8) NOT NULL DEFAULT '0' AFTER `type`,
ADD `category` char(30) NOT NULL AFTER `type`,
ADD `program` mediumint(8) NOT NULL DEFAULT '0' AFTER `category`,
ADD `budget` varchar(30) NOT NULL DEFAULT '0' AFTER `program`,
ADD `budgetUnit` char(30) NOT NULL DEFAULT 'yuan' AFTER `budget`;

View File

@@ -130,7 +130,7 @@ $lang->mainNav->recent = '<i class="icon icon-menu-recent"></i> 近期|recent|i
$lang->dividerMenu = ',admin,recent,';
$lang->menu = new stdclass();
$lang->menu->project = new stdclass();
$lang->menu->project = '';
/* 查询条中可以选择的对象列表。*/
$lang->searchObjects['bug'] = 'Bug';

View File

@@ -11,20 +11,13 @@ class program extends control
{
if(common::hasPriv('program', 'create')) $this->lang->pageActions = html::a($this->createLink('program', 'create'), "<i class='icon icon-sm icon-plus'></i> " . $this->lang->program->create, '', "class='btn btn-primary'");
//$programType = $this->cookie->programType;
$programType = 'bylist';
$programType = $this->cookie->programType;
if($programType == 'bylist')
{
$this->app->loadClass('pager', $static = true);
$pager = new pager($recTotal, $recPerPage, $pageID);
$projectList = $this->project->getProjectStats($status, 0, 0, 30, $orderBy, $pager, 'program');
$this->view->pager = $pager;
}
$this->app->loadClass('pager', $static = true);
$pager = new pager($recTotal, $recPerPage, $pageID);
$this->view->pager = $pager;
if(!$programType || $programType == 'bygrid') $projectList = $this->project->getList($status, 0, 0, 0, 'program');
$this->view->projectList = $projectList;
$this->view->projectList = $this->program->getList($status, $orderBy, $pager);
$this->view->status = $status;
$this->view->orderBy = $orderBy;
$this->view->users = $this->loadModel('user')->getPairs('noletter');
@@ -34,7 +27,7 @@ class program extends control
$this->display();
}
public function create()
public function create($type = 'scrum', $copyProgramID = '')
{
if($_POST)
{
@@ -47,10 +40,33 @@ class program extends control
$this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => inlink('index')));
}
$this->view->pmUsers = $this->loadModel('user')->getPairs('noclosed|nodeleted|pmfirst');
$this->view->title = $this->lang->program->create;
$this->view->position[] = $this->lang->program->create;
$this->view->groups = $this->loadModel('group')->getPairs();
$name = '';
$code = '';
$team = '';
$whitelist = '';
$acl = 'open';
if($copyProgramID)
{
$copyProgram = $this->dao->select('*')->from(TABLE_PROJECT)->where('id')->eq($copyProgramID)->fetch();
$name = $copyProgram->name;
$code = $copyProgram->code;
$team = $copyProgram->team;
$acl = $copyProgram->acl;
$whitelist = $copyProgram->whitelist;
}
$this->view->title = $this->lang->program->create;
$this->view->position[] = $this->lang->program->create;
$this->view->groups = $this->loadModel('group')->getPairs();
$this->view->pmUsers = $this->loadModel('user')->getPairs('noclosed|nodeleted|pmfirst');
$this->view->programs = array('' => '') + $this->program->getPairsByType($type);
$this->view->type = $type;
$this->view->name = $name;
$this->view->code = $code;
$this->view->team = $team;
$this->view->acl = $acl;
$this->view->whitelist = $whitelist;
$this->view->copyProgramID = $copyProgramID;
$this->display();
}

View File

@@ -0,0 +1,9 @@
#copyProjectModal {padding: 0}
#copyProjectModal {padding: 0 2px}
#copyProjectModal > div {position: relative;}
#copyProjectModal a {display: block; min-height: 30px; line-height: 30px; padding: 5px 15px; border: 1px solid #e5e5e5; color: #333; margin: 5px 0; border-radius: 3px;}
#copyProjectModal a > i {display: inline-block; margin-right: 5px;}
#copyProjectModal a:hover {border:1px solid #00a9fc; background-color: #E9F2FB; text-decoration: none}
#copyProjectModal a.active {border-color: #00da88; color: #00da88; background-color: #E5FFE6}
#copyProjectModal a.active:after {position: absolute; content: '\e92f'; font-family: ZentaoIcon; font-size: 20px; right: 25px;}
#copyProjectModal a.cancel {color: #ff5d5d}

View File

@@ -1,9 +1,3 @@
$().ready(function()
{
$('#navbar').find('li').removeClass('active');
if(typeof(status) == 'undefined' || !status) status = 'all';
$('#navbar').find('a[href*=' + status + ']').parent().addClass('active');
});
function setWhite(acl)
{
acl == 'custom' ? $('#whitelistBox').removeClass('hidden') : $('#whitelistBox').addClass('hidden');
@@ -14,3 +8,104 @@ function setProgramType(type)
$.cookie('programType', type, {expires:config.cookieLife, path:config.webRoot});
location.href = location.href;
}
/**
* Convert a date string like 2011-11-11 to date object in js.
*
* @param string $date
* @access public
* @return date
*/
function convertStringToDate(dateString)
{
dateString = dateString.split('-');
return new Date(dateString[0], dateString[1] - 1, dateString[2]);
}
/**
* Compute delta of two days.
*
* @param string $date1
* @param string $date1
* @access public
* @return int
*/
function computeDaysDelta(date1, date2)
{
date1 = convertStringToDate(date1);
date2 = convertStringToDate(date2);
delta = (date2 - date1) / (1000 * 60 * 60 * 24) + 1;
weekEnds = 0;
for(i = 0; i < delta; i++)
{
if((weekend == 2 && date1.getDay() == 6) || date1.getDay() == 0) weekEnds ++;
date1 = date1.valueOf();
date1 += 1000 * 60 * 60 * 24;
date1 = new Date(date1);
}
return delta - weekEnds;
}
/**
* Compute work days.
*
* @access public
* @return void
*/
function computeWorkDays(currentID)
{
isBactchEdit = false;
if(currentID)
{
index = currentID.replace('begins[', '');
index = index.replace('ends[', '');
index = index.replace(']', '');
if(!isNaN(index)) isBactchEdit = true;
}
if(isBactchEdit)
{
beginDate = $('#begins\\[' + index + '\\]').val();
endDate = $('#ends\\[' + index + '\\]').val();
}
else
{
beginDate = $('#begin').val();
endDate = $('#end').val();
}
if(beginDate && endDate)
{
if(isBactchEdit) $('#dayses\\[' + index + '\\]').val(computeDaysDelta(beginDate, endDate));
if(!isBactchEdit) $('#days').val(computeDaysDelta(beginDate, endDate));
}
else if($('input[checked="true"]').val())
{
computeEndDate();
}
}
/**
* Compute the end date for project.
*
* @param int $delta
* @access public
* @return void
*/
function computeEndDate(delta)
{
beginDate = $('#begin').val();
if(!beginDate) return;
delta = parseInt(delta);
beginDate = convertStringToDate(beginDate);
if((delta == 7 || delta == 14) && (beginDate.getDay() == 1))
{
delta = (weekend == 2) ? (delta - 2) : (delta - 1);
}
endDate = beginDate.addDays(delta - 1).toString('yyyy-MM-dd');
$('#end').val(endDate).datetimepicker('update');
computeWorkDays();
}

View File

@@ -0,0 +1,9 @@
$(function()
{
$('#copyProjects a').click(function(){setCopyProject($(this).data('id')); $('#copyProjectModal').modal('hide')});
});
function setCopyProject(programID)
{
location.href = createLink('program', 'create', 'type=' + type + '&copyProgramID=' + programID);
}

View File

@@ -3,7 +3,8 @@ $lang->program->index = '项目主页';
$lang->program->common = '项目';
$lang->program->stage = '阶段';
$lang->program->name = '项目名称';
$lang->program->type = '项目类型';
$lang->program->type = '管理方式';
$lang->program->category = '项目类型';
$lang->program->desc = '项目描述';
$lang->program->code = '项目代号';
$lang->program->begin = '计划开始日期';
@@ -33,3 +34,6 @@ $lang->program->unitList['dollar'] = 'Dollars';
$lang->program->typeList['scrum'] = "Scrum";
$lang->program->typeList['cmmi'] = "瀑布";
$lang->program->categoryList['single'] = "单产品项目";
$lang->program->categoryList['multiple'] = "多产品项目";

View File

@@ -1,12 +1,35 @@
<?php
class programModel extends model
{
public function getList($status = 'all', $orderBy = 'id_desc', $pager = NULL)
{
return $this->dao->select('*')->from(TABLE_PROJECT)
->where('iscat')->eq(0)
->andWhere('program')->eq(0)
->andWhere('deleted')->eq(0)
->beginIF(!$this->app->user->admin)->andWhere('id')->in($this->app->user->view->projects)->fi()
->beginIF($status != 'all')->andWhere('status')->eq($status)->fi()
->orderBy($orderBy)
->page($pager)
->fetchAll('id');
}
public function getPairsByType($type)
{
return $this->dao->select('id, name')->from(TABLE_PROJECT)
->where('iscat')->eq(0)
->andWhere('type')->eq($type)
->andWhere('program')->eq(0)
->andWhere('deleted')->eq(0)
->beginIF(!$this->app->user->admin)->andWhere('id')->in($this->app->user->view->projects)->fi()
->fetchPairs();
}
public function create()
{
$this->lang->project->team = $this->lang->project->teamname;
$project = fixer::input('post')
->setDefault('status', 'wait')
->setDefault('type', 'program')
->setIF($this->post->acl != 'custom', 'whitelist', '')
->setDefault('openedBy', $this->app->user->account)
->setDefault('openedDate', helper::now())
@@ -28,13 +51,14 @@ class programModel extends model
/* Add the creater to the team. */
if(!dao::isError())
{
$projectID = $this->dao->lastInsertId();
$today = helper::today();
$programID = $this->dao->lastInsertId();
$today = helper::today();
/* Save order. */
$this->dao->update(TABLE_PROJECT)->set('`order`')->eq($projectID * 5)->where('id')->eq($projectID)->exec();
$this->file->updateObjectID($this->post->uid, $projectID, 'project');
$this->dao->update(TABLE_PROJECT)->set('`order`')->eq($programID * 5)->where('id')->eq($programID)->exec();
$this->file->updateObjectID($this->post->uid, $programID, 'project');
/*
$product = new stdclass();
$product->name = $project->name;
$product->project = $projectID;
@@ -46,8 +70,9 @@ class programModel extends model
$productID = $this->dao->lastInsertId();
$this->dao->update(TABLE_PRODUCT)->set('`order`')->eq($productID * 5)->where('id')->eq($productID)->exec();
*/
/* Create doc lib. */
/* Create doc lib.
$this->app->loadLang('doc');
$lib = new stdclass();
$lib->product = $productID;
@@ -60,13 +85,13 @@ class programModel extends model
$docLibID = $this->dao->lastInsertId();
$this->loadModel('doc')->syncDocModule($docLibID);
/* Insert into projectproduct. */
//$data = new stdclass();
//$data->project = $projectID;
//$data->product = $productID;
//$this->dao->insert(TABLE_PROJECTPRODUCT)->data($data)->exec();
$data = new stdclass();
$data->project = $projectID;
$data->product = $productID;
$this->dao->insert(TABLE_PROJECTPRODUCT)->data($data)->exec();
*/
return $projectID;
return $programID;
}
}

View File

@@ -38,21 +38,28 @@
<div class='center-block'>
<div class='main-header'>
<h2><?php echo $lang->program->create;?></h2>
<div class="pull-right btn-toolbar">
<button type='button' class='btn btn-link' data-toggle='modal' data-target='#copyProjectModal'><?php echo html::icon($lang->icons['copy'], 'muted') . ' ' . $lang->project->copy;?></button>
</div>
</div>
<form class='form-indicator main-form form-ajax' method='post' target='hiddenwin' id='dataform'>
<table class='table table-form'>
<tr>
<th class='w-120px'><?php echo $lang->program->type;?></th>
<td><?php echo html::select('type', $lang->program->typeList, '', "class='form-control'");?></td><td></td><td></td>
<td><?php echo zget($lang->program->typeList, $type, '');?></td><td></td><td></td>
</tr>
<tr>
<th><?php echo $lang->program->name;?></th>
<td class="col-main"><?php echo html::input('name', '', "class='form-control' required");?></td>
<td class="col-main"><?php echo html::input('name', $name, "class='form-control' required");?></td>
<td></td><td></td>
</tr>
<tr>
<th><?php echo $lang->program->code;?></th>
<td><?php echo html::input('code', '', "class='form-control' required");?></td><td></td><td></td>
<td><?php echo html::input('code', $code, "class='form-control' required");?></td><td></td><td></td>
</tr>
<tr>
<th><?php echo $lang->program->category;?></th>
<td><?php echo html::select('category', $lang->program->categoryList, '', "class='form-control'");?></td><td></td><td></td>
</tr>
<tr>
<th><?php echo $lang->program->PM;?></th>
@@ -67,20 +74,32 @@
<th><?php echo $lang->program->dateRange;?></th>
<td>
<div class='input-group'>
<?php echo html::input('begin', date('Y-m-d'), "class='form-control form-date' placeholder='" . $lang->program->begin . "' required");?>
<?php echo html::input('begin', date('Y-m-d'), "class='form-control form-date' onchange='computeWorkDays();' placeholder='" . $lang->program->begin . "' required");?>
<span class='input-group-addon'><?php echo $lang->program->to;?></span>
<?php echo html::input('end', '', "class='form-control form-date' placeholder='" . $lang->program->end . "' required");?>
<?php echo html::input('end', '', "class='form-control form-date' onchange='computeWorkDays();' placeholder='" . $lang->program->end . "' required");?>
</div>
</td>
<td colspan='2'></td>
</tr>
<?php if($type == 'scrum'):?>
<tr>
<th><?php echo $lang->project->days;?></th>
<td>
<div class='input-group'>
<?php echo html::input('days', '', "class='form-control'");?>
<span class='input-group-addon'><?php echo $lang->project->day;?></span>
</div>
</td><td></td><td></td>
</tr>
<?php endif;?>
<tr>
<th><?php echo $lang->project->teamname;?></th>
<td><?php echo html::input('team', '', "class='form-control'");?></td><td></td><td></td>
<td><?php echo html::input('team', $team, "class='form-control'");?></td><td></td><td></td>
</tr>
<tr class='hide'>
<th><?php echo $lang->project->status;?></th>
<td><?php echo html::hidden('status', 'wait');?></td>
<td><?php echo html::hidden('type', $type);?></td>
<td></td>
<td></td>
</tr>
@@ -94,11 +113,11 @@
</tr>
<tr>
<th><?php echo $lang->project->acl;?></th>
<td colspan='3'><?php echo nl2br(html::radio('acl', $lang->project->aclList, 'open', "onclick='setWhite(this.value);'", 'block'));?></td>
<td colspan='3'><?php echo nl2br(html::radio('acl', $lang->project->aclList, $acl, "onclick='setWhite(this.value);'", 'block'));?></td>
</tr>
<tr id='whitelistBox' class='hidden'>
<th><?php echo $lang->project->whitelist;?></th>
<td colspan='3'><?php echo html::checkbox('whitelist', $groups, '', '', '', 'inline');?></td>
<td colspan='3'><?php echo html::checkbox('whitelist', $groups, $whitelist, '', '', 'inline');?></td>
</tr>
<tr>
<td colspan='4' class='text-center form-actions'>
@@ -111,4 +130,33 @@
</form>
</div>
</div>
<div class='modal fade modal-scroll-inside' id='copyProjectModal'>
<div class='modal-dialog mw-900px'>
<div class='modal-header'>
<button type='button' class='close' data-dismiss='modal'><i class="icon icon-close"></i></button>
<h4 class='modal-title' id='myModalLabel'><?php echo $lang->project->copyTitle;?></h4>
</div>
<div class='modal-body'>
<?php if(count($programs) == 1):?>
<div class='alert with-icon'>
<i class='icon-exclamation-sign'></i>
<div class='content'><?php echo $lang->project->copyNoProject;?></div>
</div>
<?php else:?>
<div id='copyProjects' class='row'>
<?php foreach ($programs as $id => $name):?>
<?php if(empty($id)):?>
<?php if($copyProgramID != 0):?>
<div class='col-md-4 col-sm-6'><a href='javascript:;' data-id='' class='cancel'><?php echo html::icon($lang->icons['cancel']) . ' ' . $lang->project->cancelCopy;?></a></div>
<?php endif;?>
<?php else: ?>
<div class='col-md-4 col-sm-6'><a href='javascript:;' data-id='<?php echo $id;?>' class='nobr <?php echo ($copyProgramID == $id) ? ' active' : '';?>'><?php echo html::icon($lang->icons['project'], 'text-muted') . ' ' . $name;?></a></div>
<?php endif; ?>
<?php endforeach;?>
</div>
<?php endif;?>
</div>
</div>
</div>
<?php js::set('type', $type);?>
<?php include '../../common/view/footer.html.php';?>

View File

@@ -78,12 +78,13 @@
<?php $vars = "status=$status&orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}";?>
<thead>
<tr>
<th class='c-id'>
<?php common::printOrderLink('id', $orderBy, $vars, $lang->idAB);?>
</th>
<th><?php common::printOrderLink('name', $orderBy, $vars, $lang->program->name);?></th>
<th class='c-id w-60px'><?php common::printOrderLink('id', $orderBy, $vars, $lang->idAB);?></th>
<th class='w-120px'><?php common::printOrderLink('code', $orderBy, $vars, $lang->program->code);?></th>
<th class='w-120px'><?php common::printOrderLink('budget', $orderBy, $vars, $lang->program->budget);?></th>
<th><?php common::printOrderLink('name', $orderBy, $vars, $lang->program->name);?></th>
<th class='w-100px'><?php common::printOrderLink('type', $orderBy, $vars, $lang->program->type);?></th>
<th class='w-100px'><?php common::printOrderLink('begin', $orderBy, $vars, $lang->program->begin);?></th>
<th class='w-100px'><?php common::printOrderLink('end', $orderBy, $vars, $lang->program->end);?></th>
<th class='w-100px'><?php common::printOrderLink('budget', $orderBy, $vars, $lang->program->budget);?></th>
<th class='w-100px'><?php common::printOrderLink('PM', $orderBy, $vars, $lang->program->PM);?></th>
<th class='w-200px text-left'><?php echo $lang->program->desc;?></th>
<th class='text-center w-200px'><?php echo $lang->actions;?></th>
@@ -92,13 +93,14 @@
<tbody class='sortable' id='projectTableList'>
<?php foreach($projectList as $project):?>
<tr data-id='<?php echo $project->id ?>' data-order='<?php echo $project->order ?>'>
<td class='c-id'>
<?php printf('%03d', $project->id);?>
</td>
<td class='c-id'><?php printf('%03d', $project->id);?></td>
<td class='text-left'><?php echo $project->code;?></td>
<td class='text-left' title='<?php echo $project->name?>'>
<?php echo html::a($this->createLink('project', 'task', 'projectID=' . $project->id), $project->name);?>
</td>
<td class='text-left'><?php echo $project->code;?></td>
<td class='text-center'><?php echo zget($lang->program->typeList, $project->type, '');?></td>
<td class='text-center'><?php echo $project->begin;?></td>
<td class='text-center'><?php echo $project->end;?></td>
<td class='text-left'><?php echo $project->budget . ' ' . zget($lang->program->unitList, $project->budgetUnit);?></td>
<td><?php echo zget($users, $project->PM);?></td>
<td title='<?php echo strip_tags($project->desc);?>'><?php echo strip_tags($project->desc);?></td>