* Add category to product.

This commit is contained in:
liugang
2017-10-30 17:55:55 +08:00
parent fd35539014
commit 6dd2154233
12 changed files with 125 additions and 72 deletions
+2
View File
@@ -64,6 +64,8 @@ CREATE TABLE IF NOT EXISTS `zt_log` (
KEY `obejctID` (`objectID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
ALTER TABLE `zt_product` ADD `category` mediumint(8) NOT NULL AFTER `code`;
ALTER TABLE `zt_task` ADD `parent` INT(11) NULL DEFAULT '0' AFTER `deleted`;
ALTER TABLE `zt_team` ADD `task` INT(11) NULL DEFAULT '0' AFTER `project`;
ALTER TABLE `zt_team` ADD `estimate` DECIMAL(12,2) UNSIGNED NOT NULL DEFAULT '0';
+15 -14
View File
@@ -187,20 +187,21 @@ $lang->score->menu = $lang->my->menu;
$lang->product = new stdclass();
$lang->product->menu = new stdclass();
$lang->product->menu->list = array('link' => '%s', 'fixed' => true);
$lang->product->menu->story = array('link' => 'Story|product|browse|productID=%s', 'alias' => 'batchedit', 'subModule' => 'story');
$lang->product->menu->dynamic = 'Dynamic|product|dynamic|productID=%s';
$lang->product->menu->plan = array('link' => 'Plan|productplan|browse|productID=%s', 'subModule' => 'productplan');
$lang->product->menu->release = array('link' => 'Release|release|browse|productID=%s', 'subModule' => 'release');
$lang->product->menu->roadmap = 'Roadmap|product|roadmap|productID=%s';
$lang->product->menu->doc = array('link' => 'Document|doc|objectLibs|type=product&objectID=%s&from=product', 'subModule' => 'doc');
$lang->product->menu->branch = '@branch@|branch|manage|productID=%s';
$lang->product->menu->module = 'Module|tree|browse|productID=%s&view=story';
$lang->product->menu->view = array('link' => 'Overview|product|view|productID=%s', 'alias' => 'edit');
$lang->product->menu->project = "{$lang->projectCommon}|product|project|status=all&productID=%s";
$lang->product->menu->create = array('link' => "<i class='icon-plus'></i>&nbsp;Add{$lang->productCommon}|product|create", 'float' => 'right');
$lang->product->menu->all = array('link' => "<i class='icon-cubes'></i>&nbsp;All{$lang->productCommon}|product|all|productID=%s", 'float' => 'right');
$lang->product->menu->index = array('link' => "<i class='icon-home'></i>{$lang->productCommon}Homepage|product|index|locate=no", 'float' => 'right');
$lang->product->menu->list = array('link' => '%s', 'fixed' => true);
$lang->product->menu->story = array('link' => 'Story|product|browse|productID=%s', 'alias' => 'batchedit', 'subModule' => 'story');
$lang->product->menu->dynamic = 'Dynamic|product|dynamic|productID=%s';
$lang->product->menu->plan = array('link' => 'Plan|productplan|browse|productID=%s', 'subModule' => 'productplan');
$lang->product->menu->release = array('link' => 'Release|release|browse|productID=%s', 'subModule' => 'release');
$lang->product->menu->roadmap = 'Roadmap|product|roadmap|productID=%s';
$lang->product->menu->doc = array('link' => 'Document|doc|objectLibs|type=product&objectID=%s&from=product', 'subModule' => 'doc');
$lang->product->menu->branch = '@branch@|branch|manage|productID=%s';
$lang->product->menu->module = 'Module|tree|browse|productID=%s&view=story';
$lang->product->menu->category = 'Category|tree|browse|productID=%s&view=category';
$lang->product->menu->view = array('link' => 'Overview|product|view|productID=%s', 'alias' => 'edit');
$lang->product->menu->project = "{$lang->projectCommon}|product|project|status=all&productID=%s";
$lang->product->menu->create = array('link' => "<i class='icon-plus'></i>&nbsp;Add{$lang->productCommon}|product|create", 'float' => 'right');
$lang->product->menu->all = array('link' => "<i class='icon-cubes'></i>&nbsp;All{$lang->productCommon}|product|all|productID=%s", 'float' => 'right');
$lang->product->menu->index = array('link' => "<i class='icon-home'></i>{$lang->productCommon}Homepage|product|index|locate=no", 'float' => 'right');
$lang->story = new stdclass();
$lang->productplan = new stdclass();
+1
View File
@@ -40,6 +40,7 @@ $lang->product->menuOrder[40] = 'doc';
$lang->product->menuOrder[45] = 'project';
$lang->product->menuOrder[50] = 'branch';
$lang->product->menuOrder[55] = 'module';
$lang->product->menuOrder[57] = 'category';
$lang->product->menuOrder[60] = 'view';
$lang->product->menuOrder[65] = 'create';
$lang->product->menuOrder[70] = 'all';
+16 -14
View File
@@ -187,20 +187,21 @@ $lang->score->menu = $lang->my->menu;
$lang->product = new stdclass();
$lang->product->menu = new stdclass();
$lang->product->menu->list = array('link' => '%s', 'fixed' => true);
$lang->product->menu->story = array('link' => '需求|product|browse|productID=%s', 'alias' => 'batchedit', 'subModule' => 'story');
$lang->product->menu->dynamic = '动态|product|dynamic|productID=%s';
$lang->product->menu->plan = array('link' => '计划|productplan|browse|productID=%s', 'subModule' => 'productplan');
$lang->product->menu->release = array('link' => '发布|release|browse|productID=%s', 'subModule' => 'release');
$lang->product->menu->roadmap = '路线图|product|roadmap|productID=%s';
$lang->product->menu->doc = array('link' => '文档|doc|objectLibs|type=product&objectID=%s&from=product', 'subModule' => 'doc');
$lang->product->menu->branch = '@branch@|branch|manage|productID=%s';
$lang->product->menu->module = '模块|tree|browse|productID=%s&view=story';
$lang->product->menu->view = array('link' => '概况|product|view|productID=%s', 'alias' => 'edit');
$lang->product->menu->project = "{$lang->projectCommon}|product|project|status=all&productID=%s";
$lang->product->menu->create = array('link' => "<i class='icon-plus'></i>&nbsp;添加{$lang->productCommon}|product|create", 'float' => 'right');
$lang->product->menu->all = array('link' => "<i class='icon-cubes'></i>&nbsp;所有{$lang->productCommon}|product|all|productID=%s", 'float' => 'right');
$lang->product->menu->index = array('link' => "<i class='icon-home'></i>{$lang->productCommon}主页|product|index|locate=no", 'float' => 'right');
$lang->product->menu->list = array('link' => '%s', 'fixed' => true);
$lang->product->menu->story = array('link' => '需求|product|browse|productID=%s', 'alias' => 'batchedit', 'subModule' => 'story');
$lang->product->menu->dynamic = '动态|product|dynamic|productID=%s';
$lang->product->menu->plan = array('link' => '计划|productplan|browse|productID=%s', 'subModule' => 'productplan');
$lang->product->menu->release = array('link' => '发布|release|browse|productID=%s', 'subModule' => 'release');
$lang->product->menu->roadmap = '路线图|product|roadmap|productID=%s';
$lang->product->menu->doc = array('link' => '文档|doc|objectLibs|type=product&objectID=%s&from=product', 'subModule' => 'doc');
$lang->product->menu->branch = '@branch@|branch|manage|productID=%s';
$lang->product->menu->module = '模块|tree|browse|productID=%s&view=story';
$lang->product->menu->category = '目录|tree|browse|productID=%s&view=category';
$lang->product->menu->view = array('link' => '概况|product|view|productID=%s', 'alias' => 'edit');
$lang->product->menu->project = "{$lang->projectCommon}|product|project|status=all&productID=%s";
$lang->product->menu->create = array('link' => "<i class='icon-plus'></i>&nbsp;添加{$lang->productCommon}|product|create", 'float' => 'right');
$lang->product->menu->all = array('link' => "<i class='icon-cubes'></i>&nbsp;所有{$lang->productCommon}|product|all|productID=%s", 'float' => 'right');
$lang->product->menu->index = array('link' => "<i class='icon-home'></i>{$lang->productCommon}主页|product|index|locate=no", 'float' => 'right');
$lang->story = new stdclass();
$lang->productplan = new stdclass();
@@ -787,6 +788,7 @@ if(isset($config->global->flow) and $config->global->flow == 'onlyTest')
unset($lang->product->menu->roadmap);
unset($lang->product->menu->doc);
unset($lang->product->menu->module);
unset($lang->product->menu->category);
unset($lang->product->menu->index);
$lang->product->menu->build = array('link' => '版本|product|build', 'subModule' => 'build');
+2
View File
@@ -231,6 +231,7 @@ class product extends control
$this->view->poUsers = $this->loadModel('user')->getPairs('nodeleted|pofirst|noclosed');
$this->view->qdUsers = $this->loadModel('user')->getPairs('nodeleted|qdfirst|noclosed');
$this->view->rdUsers = $this->loadModel('user')->getPairs('nodeleted|devfirst|noclosed');
$this->view->categories = $this->loadModel('tree')->getOptionMenu($rootID = 0, $type = 'category');
unset($this->lang->product->typeList['']);
$this->display();
@@ -275,6 +276,7 @@ class product extends control
$this->view->poUsers = $this->loadModel('user')->getPairs('nodeleted|pofirst', $product->PO);
$this->view->qdUsers = $this->loadModel('user')->getPairs('nodeleted|qdfirst', $product->QD);
$this->view->rdUsers = $this->loadModel('user')->getPairs('nodeleted|devfirst', $product->RD);
$this->view->categories = $this->loadModel('tree')->getOptionMenu($rootID = 0, $type = 'category');
unset($this->lang->product->typeList['']);
$this->display();
+1
View File
@@ -58,6 +58,7 @@ $lang->product->accessDenied = "您无权访问该{$lang->productCommon}";
$lang->product->id = "编号";
$lang->product->name = "{$lang->productCommon}名称";
$lang->product->code = "{$lang->productCommon}代号";
$lang->product->category = "{$lang->productCommon}目录";
$lang->product->order = '排序';
$lang->product->type = "{$lang->productCommon}类型";
$lang->product->status = '状态';
+4
View File
@@ -30,6 +30,10 @@
<th><?php echo $lang->product->code;?></th>
<td><?php echo html::input('code', '', "class='form-control' autocomplete='off'");?></td><td></td>
</tr>
<tr>
<th><?php echo $lang->product->category;?></th>
<td><?php echo html::select('category', $categories, '', "class='form-control chosen'");?></td><td></td>
</tr>
<tr>
<th><?php echo $lang->product->PO;?></th>
<td><?php echo html::select('PO', $poUsers, $this->app->user->account, "class='form-control chosen'");?></td><td></td>
+4
View File
@@ -31,6 +31,10 @@
<th><?php echo $lang->product->code;?></th>
<td><?php echo html::input('code', $product->code, "class='form-control' autocomplete='off'");?></td><td></td>
</tr>
<tr>
<th><?php echo $lang->product->category;?></th>
<td><?php echo html::select('category', $categories, $product->category, "class='form-control chosen'");?></td><td></td>
</tr>
<tr>
<th><?php echo $lang->product->PO;?></th>
<td><?php echo html::select('PO', $poUsers, $product->PO, "class='form-control chosen'");?></td><td></td>
+19 -2
View File
@@ -25,7 +25,7 @@ class tree extends control
public function browse($rootID, $viewType, $currentModuleID = 0, $branch = 0)
{
/* According to the type, set the module root and modules. */
if(strpos('story|bug|case', $viewType) !== false)
if(strpos('story|bug|case|category', $viewType) !== false)
{
$product = $this->loadModel('product')->getById($rootID);
if($product->type != 'normal')
@@ -95,7 +95,6 @@ class tree extends control
if($this->config->global->flow == 'onlyTest') $this->lang->set('menugroup.tree', 'testcase');
if($this->config->global->flow != 'onlyTest') $this->lang->set('menugroup.tree', 'qa');
$title = $product->name . $this->lang->colon . $this->lang->tree->manageCase;
$position[] = html::a($this->createLink('testcase', 'browse', "product=$rootID"), $product->name);
$position[] = $this->lang->tree->manageCase;
@@ -123,6 +122,24 @@ class tree extends control
$position[] = html::a($this->createLink('doc', 'browse', "libID=$rootID"), $lib->name);
$position[] = $this->lang->tree->manageCustomDoc;
}
elseif($viewType == 'category')
{
$this->lang->set('menugroup.tree', 'product');
$this->product->setMenu($this->product->getPairs(), $rootID, $branch, 'category', '', 'category');
$this->lang->tree->menu = $this->lang->product->menu;
$this->lang->tree->menuOrder = $this->lang->product->menuOrder;
$products = $this->product->getPairs();
unset($products[$rootID]);
$currentProduct = key($products);
$this->view->allProduct = $products;
$this->view->currentProduct = $currentProduct;
$this->view->productModules = $this->tree->getOptionMenu($currentProduct, 'category');
$title = $this->lang->product->common . $this->lang->colon . $this->lang->tree->manageCategory;
$position[] = $this->lang->tree->manageCategory;
}
$parentModules = $this->tree->getParents($currentModuleID);
$this->view->title = $title;
+41 -37
View File
@@ -10,30 +10,32 @@
* @link http://www.zentao.net
*/
$lang->tree = new stdclass();
$lang->tree->common = '模块维护';
$lang->tree->edit = '编辑';
$lang->tree->delete = '删除模块';
$lang->tree->browse = '通用模块维护';
$lang->tree->browseTask = '任务模块维护';
$lang->tree->manage = '维护模块';
$lang->tree->fix = '修正数据';
$lang->tree->manageProduct = "维护{$lang->productCommon}视图模块";
$lang->tree->manageProject = "维护{$lang->projectCommon}视图模块";
$lang->tree->manageBug = '维护测试视图模块';
$lang->tree->manageCase = '维护用例视图模块';
$lang->tree->manageCaseLib = '维护测试库模块';
$lang->tree->manageCustomDoc = '维护文档库分类';
$lang->tree->updateOrder = '更新排序';
$lang->tree->manageChild = '维护子模块';
$lang->tree->manageStoryChild = '维护子模块';
$lang->tree->manageBugChild = '维护Bug子模块';
$lang->tree->manageCaseChild = '维护用例子模块';
$lang->tree->manageCaselibChild = '维护测试库子模块';
$lang->tree->manageTaskChild = "维护{$lang->projectCommon}子模块";
$lang->tree->syncFromProduct = '复制';
$lang->tree->dragAndSort = "拖放排序";
$lang->tree->sort = "排序";
$lang->tree->addChild = "增加子模块";
$lang->tree->common = '模块维护';
$lang->tree->edit = '编辑';
$lang->tree->delete = '删除模块';
$lang->tree->browse = '通用模块维护';
$lang->tree->browseTask = '任务模块维护';
$lang->tree->manage = '维护模块';
$lang->tree->fix = '修正数据';
$lang->tree->manageProduct = "维护{$lang->productCommon}视图模块";
$lang->tree->manageProject = "维护{$lang->projectCommon}视图模块";
$lang->tree->manageCategory = '维护目录';
$lang->tree->manageBug = '维护测试视图模块';
$lang->tree->manageCase = '维护用例视图模块';
$lang->tree->manageCaseLib = '维护测试库模块';
$lang->tree->manageCustomDoc = '维护文档库分类';
$lang->tree->updateOrder = '更新排序';
$lang->tree->manageChild = '维护子模块';
$lang->tree->manageStoryChild = '维护子模块';
$lang->tree->manageCategoryChild = '维护子目录';
$lang->tree->manageBugChild = '维护Bug子模块';
$lang->tree->manageCaseChild = '维护用例子模块';
$lang->tree->manageCaselibChild = '维护测试库子模块';
$lang->tree->manageTaskChild = "维护{$lang->projectCommon}子模块";
$lang->tree->syncFromProduct = '复制';
$lang->tree->dragAndSort = "拖放排序";
$lang->tree->sort = "排序";
$lang->tree->addChild = "增加子模块";
$lang->tree->confirmDelete = '该模块及其子模块都会被删除,您确定删除吗?';
$lang->tree->confirmRoot = "模块的所属{$lang->productCommon}修改,会关联修改该模块下的需求、Bug、用例的所属{$lang->productCommon},以及{$lang->projectCommon}和{$lang->productCommon}的关联关系。该操作比较危险,请谨慎操作。是否确认修改?";
@@ -41,16 +43,18 @@ $lang->tree->successSave = '成功保存';
$lang->tree->successFixed = '成功修正数据!';
$lang->tree->repeatName = '模块名“%s”已经存在!';
$lang->tree->name = '模块名称';
$lang->tree->root = '所属根';
$lang->tree->branch = '平台/分支';
$lang->tree->path = '路径';
$lang->tree->type = '类型';
$lang->tree->parent = '上级模块';
$lang->tree->child = '子模块';
$lang->tree->owner = '负责人';
$lang->tree->order = '排序';
$lang->tree->short = '简称';
$lang->tree->all = '所有模块';
$lang->tree->projectDoc = "{$lang->projectCommon}文档";
$lang->tree->product = "所属{$lang->productCommon}";
$lang->tree->name = '模块名称';
$lang->tree->category = '目录名称';
$lang->tree->root = '所属根';
$lang->tree->branch = '平台/分支';
$lang->tree->path = '路径';
$lang->tree->type = '类型';
$lang->tree->parent = '上级模块';
$lang->tree->child = '子模块';
$lang->tree->categoryChild = '子目录';
$lang->tree->owner = '负责人';
$lang->tree->order = '排序';
$lang->tree->short = '简称';
$lang->tree->all = '所有模块';
$lang->tree->projectDoc = "{$lang->projectCommon}文档";
$lang->tree->product = "所属{$lang->productCommon}";
+8
View File
@@ -81,6 +81,8 @@ class treeModel extends model
*/
public function getOptionMenu($rootID, $type = 'story', $startModule = 0, $branch = 0)
{
if($type == 'category') $rootID = 0;
$branches = array($branch => '');
if(strpos('story|bug|case', $type) !== false)
{
@@ -312,6 +314,8 @@ class treeModel extends model
*/
public function getTreeMenu($rootID, $type = 'root', $startModule = 0, $userFunc, $extra = '', $branch = 0)
{
if($type == 'category') $rootID = 0;
$branches = array($branch => '');
if($branch)
{
@@ -945,6 +949,8 @@ class treeModel extends model
*/
public function getSons($rootID, $moduleID, $type = 'root', $branch = 0)
{
if($type == 'category') $rootID = 0;
/* if createVersion <= 4.1 or type == 'story', only get modules of its type. */
if(!$this->isMergeModule($rootID, $type) or $type == 'story')
{
@@ -1495,6 +1501,8 @@ class treeModel extends model
*/
public function getProductStructure($rootID, $viewType, $branch = 0, $currentModuleID = 0)
{
if($viewType == 'category') $rootID = 0;
$branches = array($branch => '');
$product = $this->loadModel('product')->getById($rootID);
if(strpos('story|bug|case', $viewType) !== false and empty($branch))
+12 -5
View File
@@ -12,8 +12,9 @@
?>
<?php include '../../common/view/header.html.php';?>
<?php $hasBranch = (strpos('story|bug|case', $viewType) !== false and $root->type != 'normal') ? true : false;?>
<?php $name = $viewType == 'category' ? $lang->tree->category : $lang->tree->name;?>
<div id='featurebar'>
<div class='heading'><?php echo $lang->tree->common;?></div>
<div class='heading'><?php echo $viewType == 'category' ? $lang->tree->manageCategory : $lang->tree->common;?></div>
</div>
<div class='row'>
<div class='col-sm-4'>
@@ -40,6 +41,7 @@
<div class='panel-body'>
<table class='table table-form'>
<tr>
<?php if($viewType != 'category'):?>
<td class='parentModule'>
<nobr>
<?php
@@ -53,6 +55,7 @@
?>
</nobr>
</td>
<?php endif;?>
<td id='moduleBox'>
<?php
if($viewType == 'story' and $allProduct)
@@ -80,7 +83,7 @@
for($i = 0; $i < TREE::NEW_CHILD_COUNT ; $i ++)
{
echo "<div class='row-table addedItem' style='margin-bottom:5px'>";
echo "<div class='col-table'>" . html::input("modules[]", '', "class='form-control' placeholder='{$lang->tree->name}' autocomplete='off'") . '</div>';
echo "<div class='col-table'>" . html::input("modules[]", '', "class='form-control' placeholder='{$name}' autocomplete='off'") . '</div>';
if($hasBranch) echo '<div class="col-table">' . html::select("branch[]", $branches, $branch, 'class="form-control"') . '</div>';
echo "<div class='col-table' style='width:120px'><div class='input-group'>" . html::input("shorts[]", '', "class='form-control' placeholder='{$lang->tree->short}' autocomplete='off'");
echo "<span class='input-group-btn'><a href='javascript:;' onclick='addItem(this)' class='btn btn-block'><i class='icon icon-plus'></i></a></span>";
@@ -91,7 +94,7 @@
echo "<div id='insertItemBox' class='hidden'>";
echo "<div class='row-table' style='margin-bottom:5px'>";
echo "<div class='col-table'>" . html::input("modules[]", '', "class='form-control' placeholder='{$lang->tree->name}' autocomplete='off'") . '</div>';
echo "<div class='col-table'>" . html::input("modules[]", '', "class='form-control' placeholder='{$name}' autocomplete='off'") . '</div>';
if($hasBranch) echo '<div class="col-table">' . html::select("branch[]", $branches, $branch, 'class="form-control" disabled') . '</div>';
echo "<div class='col-table' style='width:120px'><div class='input-group'>" . html::input("shorts[]", '', "class='form-control' placeholder='{$lang->tree->short}' autocomplete='off'") . html::hidden("order[]");
echo "<span class='input-group-btn' style='border-left:1px solid'><a href='javascript:;' onclick='deleteItem(this)' class='btn btn-block'><i class='icon icon-remove'></i></a></span>";
@@ -103,7 +106,9 @@
</td>
</tr>
<tr>
<?php if($viewType != 'category'):?>
<td></td>
<?php endif;?>
<td colspan='2'>
<?php
echo html::submitButton();
@@ -175,8 +180,8 @@ $(function()
subModules:
{
linkTemplate: '<?php echo helper::createLink('tree', 'browse', "rootID=$rootID&viewType=$viewType&moduleID={0}&branch={1}"); ?>',
title: '<?php echo $lang->tree->child ?>',
template: '<a href="javascript:;"><?php echo $lang->tree->child?></a>'
title: '<?php echo $viewType == 'category' ? $lang->tree->categoryChild : $lang->tree->child ?>',
template: '<a href="javascript:;"><?php echo $viewType == 'category' ? $lang->tree->categoryChild : $lang->tree->child?></a>'
}
},
action: function(event)
@@ -238,6 +243,8 @@ $(function()
});
$tree.find('[data-toggle="tooltip"]').tooltip();
$('#modulemenu > .nav > li > a[href*=tree][href*=browse]').not('[href*=<?php echo $viewType;?>]').parent().removeClass('active');
});
</script>
<?php