Merge branch 'master' of https://gitlab.zcorp.cc/easycorp/zentaopms into release/zentaopms_18.3

This commit is contained in:
caoyanyi
2023-04-07 11:22:34 +08:00
332 changed files with 2598 additions and 4503 deletions
+3
View File
@@ -443,3 +443,6 @@ $config->featureGroup->agileplus = array();
$config->featureGroup->waterfallplus = array();
$config->featureGroup->assetlib = array();
$config->featureGroup->other = array('devops', 'kanban');
$config->bi = new stdclass();
$config->bi->pickerHeight = 150;
+7 -7
View File
@@ -21,12 +21,12 @@ CREATE TABLE IF NOT EXISTS `zt_pivot` (
`desc` text NOT NULL,
`sql` mediumtext NOT NULL,
`fields` mediumtext NOT NULL,
`langs` mediumtext NOT NULL,
`langs` mediumtext NULL,
`vars` mediumtext NOT NULL,
`objects` mediumtext NULL,
`settings` mediumtext NOT NULL,
`filters` mediumtext NOT NULL,
`step` tinyint(1) unsigned NOT NULL,
`step` tinyint(1) unsigned NOT NULL DEFAULT '',
`stage` enum('draft','published') NOT NULL DEFAULT 'draft',
`builtin` enum('0', '1') NOT NULL DEFAULT '0',
`createdBy` varchar(30) NOT NULL,
@@ -44,10 +44,11 @@ CREATE TABLE `zt_chart_back` SELECT * FROM `zt_chart`;
ALTER TABLE `zt_chart` MODIFY `fields` mediumtext NOT NULL;
ALTER TABLE `zt_chart` MODIFY `group` varchar(255) NOT NULL;
ALTER TABLE `zt_chart` ADD `stage` enum('draft','published') NOT NULL DEFAULT 'draft' AFTER `sql`;
ALTER TABLE `zt_chart` ADD `langs` text NOT NULL AFTER `fields`;
ALTER TABLE `zt_chart` ADD `step` tinyint(1) unsigned NOT NULL AFTER `filters`;
ALTER TABLE `zt_chart` ADD `langs` text NULL AFTER `fields`;
ALTER TABLE `zt_chart` ADD `step` tinyint(1) unsigned NOT NULL DEFAULT '0' AFTER `filters`;
ALTER TABLE `zt_chart` DROP `dataset`;
ALTER TABLE `zt_dataview` ADD `langs` text NOT NULL AFTER `fields`;
ALTER TABLE `zt_dataview` ADD `langs` text NULL AFTER `fields`;
ALTER TABLE `zt_screen` ADD `status` enum('draft','published') NOT NULL DEFAULT 'draft' AFTER `scheme`;
ALTER TABLE `zt_screen` ADD `builtin` enum('0', '1') NOT NULL DEFAULT '0' AFTER `status`;
@@ -182,8 +183,7 @@ CHANGE `editedDate` `editedDate` datetime NULL;
ALTER TABLE `zt_assetlib`
CHANGE `editedBy` `editedBy` varchar(30) NOT NULL DEFAULT '',
CHANGE `editedDate` `editedDate` datetime NULL,
CHANGE `registerDate` `registerDate` datetime NULL;
CHANGE `editedDate` `editedDate` datetime NULL;
ALTER TABLE `zt_attend`
CHANGE `reviewedBy` `reviewedBy` char(30) NULL DEFAULT '',
+5 -6
View File
@@ -442,9 +442,9 @@ CREATE TABLE IF NOT EXISTS `zt_chart` (
`desc` text NOT NULL,
`settings` mediumtext NOT NULL,
`filters` mediumtext NOT NULL,
`step` tinyint(1) unsigned NOT NULL,
`step` tinyint(1) unsigned NOT NULL DEFAULT '0',
`fields` mediumtext NOT NULL,
`langs` text NOT NULL,
`langs` text NULL,
`sql` mediumtext,
`stage` enum('draft','published') NOT NULL DEFAULT 'draft',
`builtin` tinyint(1) unsigned NOT NULL,
@@ -584,7 +584,7 @@ CREATE TABLE IF NOT EXISTS `zt_dataview` (
`view` varchar(57) NOT NULL,
`sql` text NOT NULL,
`fields` mediumtext NOT NULL,
`langs` text NOT NULL,
`langs` text NULL,
`objects` mediumtext NOT NULL,
`createdBy` varchar(30) NOT NULL,
`createdDate` datetime NOT NULL,
@@ -9680,7 +9680,6 @@ CREATE TABLE IF NOT EXISTS `zt_assetlib` (
`createdDate` datetime NOT NULL,
`editedBy` varchar(30) NOT NULL DEFAULT '',
`editedDate` datetime NULL,
`registerDate` datetime NULL,
`deleted` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB CHARSET=utf8;
@@ -14020,12 +14019,12 @@ CREATE TABLE IF NOT EXISTS `zt_pivot` (
`desc` text NOT NULL,
`sql` mediumtext NOT NULL,
`fields` mediumtext NOT NULL,
`langs` mediumtext NOT NULL,
`langs` mediumtext NULL,
`vars` mediumtext NOT NULL,
`objects` mediumtext NULL,
`settings` mediumtext NOT NULL,
`filters` mediumtext NOT NULL,
`step` tinyint(1) unsigned NOT NULL,
`step` tinyint(1) unsigned NOT NULL DEFAULT '0',
`stage` enum('draft','published') NOT NULL DEFAULT 'draft',
`builtin` enum('0', '1') NOT NULL DEFAULT '0',
`createdBy` varchar(30) NOT NULL,
+33
View File
@@ -398,4 +398,37 @@ class dbh
{
return $this->pdo->lastInsertId($name);
}
/**
* Begin transaction.
*
* @access public
* @return bool
*/
public function beginTransaction()
{
return $this->pdo->beginTransaction();
}
/**
* Roll back if transaction failed.
*
* @access public
* @return bool
*/
public function rollBack()
{
return $this->pdo->rollBack();
}
/**
* Commit transaction.
*
* @access public
* @return bool
*/
public function commit()
{
return $this->pdo->commit();
}
}
+6 -9
View File
@@ -184,24 +184,22 @@ class api extends control
/**
* Release list.
*
* @param int $libID
* @param int $libID
* @param string $orderBy
* @access public
* @return void
*/
public function releases($libID, $orderBy = 'id', $recTotal = 0, $recPerPage = 15, $pageID = 1)
public function releases($libID, $orderBy = 'id')
{
$libs = $this->doc->getApiLibs();
$this->app->loadClass('pager', $static = true);
$this->lang->modulePageNav = $this->generateLibsDropMenu($libs[$libID]);
$pager = new pager($recTotal, $recPerPage, $pageID);
/* Append id for secend sort. */
$sort = common::appendOrder($orderBy);
$releases = $this->api->getReleaseByQuery($libID, $pager, $sort);
$releases = $this->api->getReleaseByQuery($libID, '', $sort);
$this->view->releases = $releases;
$this->view->pager = $pager;
$this->view->orderBy = $orderBy;
$this->view->title = $this->lang->api->managePublish;
$this->view->libID = $libID;
@@ -420,8 +418,6 @@ class api extends control
*/
public function createLib($type = 'product', $objectID = 0)
{
if(!in_array($type, array('product', 'project'))) $type = 'product';
if(!empty($_POST))
{
$libID = $this->doc->createApiLib();
@@ -439,7 +435,8 @@ class api extends control
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $this->createLink('api', 'index', "libID=$libID")));
}
$this->lang->api->aclList['default'] = sprintf($this->lang->api->aclList['default'], $this->lang->{$type}->common);
$defaultAclLang = in_array($type, array('product', 'product')) ? $this->lang->{$type}->common : $this->lang->product->common;
$this->lang->api->aclList['default'] = sprintf($this->lang->api->aclList['default'], $defaultAclLang);
$this->view->type = $type;
$this->view->objectID = $objectID;
+1
View File
@@ -3,3 +3,4 @@ form {margin-bottom: 100px;}
table {width: 90% !important;}
#whiteListBox div.input-group {margin-bottom: 2px;}
#whiteListBox .input-group:last-child {margin-top: 10px;}
#aclBox > th {vertical-align: top; padding-top: 18px;}
+2
View File
@@ -2,3 +2,5 @@
.c-actions {width: 60px;}
tbody tr td {white-space: nowrap; overflow: hidden; text-overflow: clip;}
#mainContent {max-height: 400px;}
#releaseListForm {margin-bottom: 20px;}
+3 -1
View File
@@ -1,4 +1,4 @@
$(document).ready(function()
$(function()
{
$('#apiForm').ajaxForm({
success: (data) => {
@@ -10,4 +10,6 @@ $(document).ready(function()
}
}
})
toggleLibType(libType);
});
+1
View File
@@ -79,4 +79,5 @@
</div>
<?php js::set('productLang', $lang->productCommon);?>
<?php js::set('projectLang', $lang->projectCommon);?>
<?php js::set('libType', $type);?>
<?php include '../../common/view/footer.lite.html.php';?>
+2 -2
View File
@@ -26,7 +26,7 @@
if($libTree and common::hasPriv('api', 'releases')) echo html::a($this->createLink('api', 'releases', "libID=$libID", 'html', true), "<i class='icon-version muted'> </i>" . $lang->api->releases, '', "class='btn btn-link iframe' data-width='800px'");
if($libTree and common::hasPriv('api', 'createRelease')) echo html::a($this->createLink('api', 'createRelease', "libID=$libID"), "<i class='icon-publish muted'> </i>" . $lang->api->createRelease, '', "class='btn btn-link iframe' data-width='800px'");
if($libTree and common::hasPriv('api', 'export') and $config->edition != 'open') echo html::a($this->createLink('api', 'export', "libID=$libID&version=$version&release=$release", 'html', true), "<i class='icon-export muted'> </i>" . $lang->export, '', "class='btn btn-link export' data-width='480px' id='export'");
if(common::hasPriv('api', 'createLib')) echo html::a($this->createLink('api', 'createLib', "type=" . ($objectType == 'project' ? 'project' : 'product') . "&objectID=$objectID"), '<i class="icon icon-plus"></i> ' . $lang->api->createLib, '', 'class="btn btn-secondary iframe" data-width="800px"');
if(common::hasPriv('api', 'createLib')) echo html::a($this->createLink('api', 'createLib', "type=" . ($objectType ? $objectType : 'nolink') . "&objectID=$objectID"), '<i class="icon icon-plus"></i> ' . $lang->api->createLib, '', 'class="btn btn-secondary iframe" data-width="800px"');
if($libTree and common::hasPriv('api', 'create')) echo html::a($this->createLink('api', 'create', "libID=$libID&moduleID=$moduleID"), '<i class="icon icon-plus"></i> ' . $lang->api->createApi, '', 'class="btn btn-primary"');
?>
</div>
@@ -37,7 +37,7 @@
<p>
<span class="text-muted"><?php echo $lang->doc->noLib;?></span>
<?php
if(common::hasPriv('api', 'createLib')) echo html::a(helper::createLink('api', 'createLib', "type=$objectType"), '<i class="icon icon-plus"></i> ' . $lang->api->createLib, '', 'class="btn btn-info iframe" data-width="800px"');
if(common::hasPriv('api', 'createLib')) echo html::a(helper::createLink('api', 'createLib', "type=" . ($objectType ? $objectType : 'nolink')), '<i class="icon icon-plus"></i> ' . $lang->api->createLib, '', 'class="btn btn-info iframe" data-width="800px"');
?>
</p>
</div>
+3 -5
View File
@@ -13,7 +13,6 @@
<?php include '../../common/view/header.html.php';?>
<div id='mainContent' class='main-row fade'>
<div class='main-col'>
<div class="cell" id="queryBox" data-module='user'></div>
<div id='mainMenu' class='clearfix'>
<div class='main-header'>
<h2><?php echo $lang->api->managePublish;?></h2>
@@ -24,11 +23,11 @@
<p><span class="text-muted"><?php echo $lang->noData;?></span></p>
</div>
<?php else:?>
<form class='main-table table-user' data-ride='table' method='post' data-checkable='false' id='userListForm'>
<table class='table has-sort-head' id='userList'>
<form class='main-table' method='post' id='releaseListForm'>
<table class='table has-sort-head' id='releaseList'>
<thead>
<tr>
<?php $vars = "libID={$libID}&orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}";?>
<?php $vars = "libID={$libID}&orderBy=%s";?>
<th class='c-id'><?php common::printOrderLink('id', $orderBy, $vars, $lang->idAB);?></th>
<th class='c-version'><?php common::printOrderLink('version', $orderBy, $vars, $lang->api->version);?></th>
<th class='c-name'><?php echo $lang->api->desc;?></th>
@@ -52,7 +51,6 @@
<?php endforeach;?>
</tbody>
</table>
<div class='table-footer'><?php $pager->show('right', 'pagerjs');?></div>
</form>
<?php endif;?>
</div>
+1 -1
View File
@@ -748,7 +748,7 @@ class block extends control
if(preg_match('/[^a-zA-Z0-9_]/', $this->params->type)) return;
$this->view->projects = $this->loadModel('project')->getPairsByProgram();
$this->view->testtasks = $this->dao->select('t1.id,t2.name as productName,t2.shadow,t3.name as buildName,t4.name as projectName')->from(TABLE_TESTTASK)->alias('t1')
$this->view->testtasks = $this->dao->select('t1.*,t2.name as productName,t2.shadow,t3.name as buildName,t4.name as projectName')->from(TABLE_TESTTASK)->alias('t1')
->leftJoin(TABLE_PRODUCT)->alias('t2')->on('t1.product=t2.id')
->leftJoin(TABLE_BUILD)->alias('t3')->on('t1.build=t3.id')
->leftJoin(TABLE_PROJECT)->alias('t4')->on('t1.execution=t4.id')
+6
View File
@@ -633,6 +633,12 @@ function loadProjectBuilds(projectID)
$.get(createLink('bug', 'ajaxGetReleasedBuilds', 'productID=' + productID), function(data){releasedBuilds = data;}, 'json');
if($('#executionIdBox #execution').val() != 0)
{
$('#executionIdBox #execution').change();
return;
}
if(page == 'create')
{
var link = createLink('build', 'ajaxGetProjectBuilds', 'projectID=' + projectID + '&productID=' + productID + '&varName=openedBuild&build=&branch=' + branch);
+2 -1
View File
@@ -285,6 +285,7 @@ class buildModel extends model
$this->app->loadLang('branch');
foreach($allBuilds as $id => $build)
{
if($build->branch === '') $build->branch = 0;
if(empty($build->releaseID) and (strpos($params, 'nodone') !== false) and ($build->objectStatus === 'done')) continue;
if((strpos($params, 'noterminate') !== false) and ($build->releaseStatus === 'terminate')) continue;
if((strpos($params, 'withexecution') !== false) and $build->execution and isset($executions[$build->execution])) continue;
@@ -439,7 +440,7 @@ class buildModel extends model
if(!isset($relationBranch[$branch])) $relationBranch[$branch] = $branch;
}
}
$build->branch = implode(',', $relationBranch);
if($relationBranch) $build->branch = implode(',', $relationBranch);
}
$product = $this->loadModel('product')->getByID($build->product);
+9
View File
@@ -0,0 +1,9 @@
<?php
$config->chart->widthInput = 128;
$config->chart->widthDate = 248;
$config->chart->dateConvert = array();
$config->chart->dateConvert['year'] = 'YEAR';
$config->chart->dateConvert['month'] = 'MONTH';
$config->chart->dateConvert['week'] = 'YEARWEEK';
$config->chart->dateConvert['day'] = 'DATE';
+257
View File
@@ -0,0 +1,257 @@
<?php
/**
* The control file of chart module of ZenTaoPMS.
*
* @copyright Copyright 2009-2015 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Chunsheng Wang <chunsheng@cnezsoft.com>
* @package chart
* @version $Id: model.php 5086 2013-07-10 02:25:22Z wyd621@gmail.com $
* @link http://www.zentao.net
*/
class chart extends control
{
/**
* Preview charts of a group.
*
* @param int $dimensionID
* @param int $groupID
* @access public
* @return void
*/
public function preview($dimensionID = 0, $groupID = 0)
{
$dimensionID = $this->loadModel('dimension')->setSwitcherMenu($dimensionID);
if(!$groupID) $groupID = $this->chart->getFirstChartGroupID($dimensionID);
list($chartTree, $charts) = $this->chart->getPreviewCharts($groupID);
if(!empty($_POST))
{
$charts = array();
foreach($this->post->charts as $value)
{
$chartID = explode('_', $value);
$group = $chartID[0];
$chartID = $chartID[1];
$chart = $this->chart->getByID($chartID);
$chart->currentGroup = $group;
$charts[] = $chart;
}
}
$this->view->title = $this->lang->chart->preview;
$this->view->dimensionID = $dimensionID;
$this->view->group = $this->loadModel('tree')->getByID($groupID);
$this->view->chartTree = $chartTree;
$this->view->charts = $charts;
$this->view->groups = $this->loadModel('tree')->getGroupPairs($dimensionID, 0, 1);
$this->display();
}
/**
* Ajax get filter form html.
*
* @param int $chartID
* @access public
* @return string
*/
public function ajaxGetFilterForm($chartID)
{
$fieldList = $this->post->fieldList;
$filters = $this->post->filters;
$fieldSettings = $this->post->fieldSettings;
$langs = $this->post->langs;
$clientLang = $this->app->getClientLang();
$fieldPairs = array();
foreach($fieldList as $field => $fieldName)
{
$fieldObject = $fieldSettings[$field]['object'];
$relatedField = $fieldSettings[$field]['field'];
$this->app->loadLang($fieldObject);
$fieldPairs[$field] = isset($this->lang->$fieldObject->$relatedField) ? $this->lang->$fieldObject->$relatedField : $field;
if(!isset($langs[$field])) continue;
if(!empty($langs[$field][$clientLang])) $fieldPairs[$field] = $langs[$field][$clientLang];
}
$htmls = array();
foreach($filters as $filter)
{
$field = $filter['field'];
$type = $filter['type'];
$default = isset($filter['default']) ? $filter['default'] : '';
$options = array();
if($type == 'select')
{
$fieldSetting = $fieldSettings[$field];
$options = $this->chart->getSysOptions(zget($fieldSetting, 'type', ''), zget($fieldSetting, 'object', ''), zget($fieldSetting, 'field', ''));
}
$filterHtml = array();
/* field html */
$filterHtml['field'] = html::select('field', $fieldPairs, $field, "class='form-control picker-select' onchange='initFilterForm(this, this.value)'");
/* default html */
$filterHtml['default'] = '';
if($type == 'input') $filterHtml['default'] .= html::input('default', $default, "class='form-control' onchange='changeDefault(this,this.value)'");
if($type == 'date' or $type == 'datetime')
{
if(empty($default)) $default = array('begin' => '', 'end' => '');
$class = $type == 'date' ? 'form-date' : 'form-datetime';
$filterHtml['default'] .= '<div class="input-group">';
$filterHtml['default'] .= html::input('default[begin]', $default['begin'], "class='form-control $class default-begin' placeholder='{$this->lang->chart->unlimited}' onchange='changeDefault(this,this.value)'");
$filterHtml['default'] .= "<span class='input-group-addon fix-border borderBox' style='border-radius: 0px;'>{$this->lang->chart->colon}</span>";
$filterHtml['default'] .= html::input('default[end]', $default['end'], "class='form-control $class default-end' placeholder='{$this->lang->chart->unlimited}' onchange='changeDefault(this,this.value)'");
$filterHtml['default'] .= '</div>';
}
if($type == 'select') $filterHtml['default'] = html::select('default[]', $options, $default, "class='form-control picker-select' onchange='changeDefault(this,this.value)' multiple");
if($type == 'condition')
{
$operator = isset($filter['operator']) ? $filter['operator'] : '';
$value = isset($filter['value']) ? $filter['value'] : '';
$hidden = strpos($operator, 'NULL') !== false ? 'hidden' : '';
$filterHtml['default'] = "<div class='conditionGroup' style='display:flex'>";
$filterHtml['default'] .= html::select('operator', $this->config->bi->conditionList, $operator, "class='form-control picker-select' onchange='changeCondition(this,this.value)'");
$filterHtml['default'] .= html::input('value', $value, "class='form-control $hidden' onchange='changeConditionValue(this,this.value)'");
$filterHtml['default'] .= "<div/>";
}
/* type html */
$filterHtml['type'] = html::select('type', $this->lang->chart->fieldTypeList, $type, "class='form-control picker-select' onchange='changeType(this, this.value)'");
/* filter item html */
$filterHtml['item'] = '';
if($type == 'input') $filterHtml['item'] .= html::input('default', $default, "class='form-control'");
if($type == 'date' or $type == 'datetime')
{
if(empty($default)) $default = array('begin' => '', 'end' => '');
$class = $type == 'date' ? 'form-date' : 'form-datetime';
$filterHtml['item'] .= '<div class="input-group">';
$filterHtml['item'] .= "<input type='text' name='default[begin]' id='default[begin]' value='{$default['begin']}' class='form-control $class default-begin' autocomplete='off' placeholder='{$this->lang->chart->unlimited}' onchange='changeDefault(this, this.value)'>";
$filterHtml['item'] .= '<span class="input-group-addon fix-border borderBox" style="border-radius: 0px;">' . $this->lang->chart->colon . '</span>';
$filterHtml['item'] .= "<input type='text' name='default[end]' id='default[end]' value='{$default['end']}' class='form-control $class default-end' autocomplete='off' placeholder='{$this->lang->chart->unlimited}' onchange='changeDefault(this, this.value)'>";
$filterHtml['item'] .= '</div>';
}
if($type == 'select') $filterHtml['item'] .= html::select('default', array('' => '') + $options, $default, "class='form-control picker-select' multiple");
if($type == 'condition')
{
$operator = isset($filter['operator']) ? $filter['operator'] : '';
$value = isset($filter['value']) ? $filter['value'] : '';
$hidden = strpos($operator, 'NULL') !== false ? 'hidden' : '';
$filterHtml['item'] = "<div class='conditionGroup' style='display:flex'>";
$filterHtml['item'] .= html::select('operator', $this->config->bi->conditionList, $operator, "class='form-control picker-select' onchange='changeCondition(this,this.value, true)'");
$filterHtml['item'] .= html::input('value', $value, "class='form-control $hidden'");
$filterHtml['item'] .= "<div/>";
}
$htmls[] = $filterHtml;
}
echo json_encode($htmls);
}
/**
* Ajax get chart.
*
* @access public
* @return void
*/
public function ajaxGetChart()
{
$post = fixer::input('post')->skipSpecial('settings,filters,sql,langs')->get();
$chartID = $post->id;
$settings = current($post->settings);
$type = $settings['type'];
$filters = isset($_POST['searchFilters']) ? $_POST['searchFilters'] : (isset($_POST['filters']) ? $post->filters : array());
$chart = $this->chart->getByID($chartID);
$filterFormat = array();
foreach($filters as $filter)
{
$field = $filter['field'];
if(!isset($filter['default'])) continue;
$default = $filter['default'];
switch($filter['type'])
{
case 'select':
if(empty($default)) break;
$default = array_filter($default, function($val){return !empty($val);});
$value = "('" . implode("', '", $default) . "')";
$filterFormat[$field] = array('operator' => 'IN', 'value' => $value);
break;
case 'input':
$filterFormat[$field] = array('operator' => 'like', 'value' => "'%$default%'");
break;
case 'date':
case 'datetime':
$begin = $default['begin'];
$end = $default['end'];
if(empty($begin) or empty($end)) break;
$value = "'$begin' and '$end'";
$filterFormat[$field] = array('operator' => 'BETWEEN', 'value' => $value);
break;
case 'condition':
$operator = $filter['operator'];
$value = $filter['value'];
if(in_array($operator, array('IN', 'NOT IN')))
{
$valueArr = explode(',', $value);
foreach($valueArr as $key => $val) $valueArr[$key] = '"' . $val . '"';
$value = '(' . implode(',', $valueArr) . ')';
}
elseif(in_array($operator, array('IS NOT NULL', 'IS NULL')))
{
$value = '';
}
$filterFormat[$field] = array('operator' => $operator, 'value' => $value);
break;
}
}
$sql = str_replace(';', '', "$post->sql");
$fields = $post->fieldSettings;
$langs = isset($post->langs) ? $post->langs : array();
switch($type)
{
case 'line':
$data = $this->chart->genLineChart($fields, $settings, $sql, $filterFormat, $langs);
break;
case 'cluBarX':
$data = $this->chart->genCluBar($fields, $settings, $sql, $filterFormat, '', $langs);
break;
case 'cluBarY':
$data = $this->chart->genCluBar($fields, $settings, $sql, $filterFormat, '', $langs);
break;
case 'pie':
$data = $this->chart->genPie($fields, $settings, $sql, $filterFormat);
break;
case 'radar':
$data = $this->chart->genRadar($fields, $settings, $sql, $filterFormat, $langs);
break;
case 'stackedBar':
$data = $this->chart->genCluBar($fields, $settings, $sql, $filterFormat, 'total', $langs);
break;
case 'stackedBarY':
$data = $this->chart->genCluBar($fields, $settings, $sql, $filterFormat, 'total', $langs);
break;
}
echo json_encode($data);
}
}
+7
View File
@@ -0,0 +1,7 @@
.table-panel {overflow-x: auto;}
.datatable {width: auto;}
.datatable th.header {line-height: 32px !important;}
.header-config {float: right; display: none;}
.header:hover .header-config {display: inline-block;}
.label-outline.label-info {border: unset; line-height: 14px;}
.border-bottom {border-bottom: 1px solid #f4f5f7;}
+51
View File
@@ -0,0 +1,51 @@
.m-chart-preview {color: rgb(49, 60, 82); background-color: rgb(244, 245, 247);}
.main-col .btn-toolbar {margin-bottom: 10px;}
.main-position {position: relative;}
.child-position {position: absolute; right: 0;}
.parent-position{padding-right: 180px;}
#chartGroups li {overflow: hidden; white-space: nowrap;}
#chartGroups .checkbox-primary {margin-left: 8px; display: inline-block;}
#chartGroups .checkbox-primary + a {display: inline-block;}
#chartGroups .checkbox-primary > input[type=checkbox][name^=chart] + label {padding-left: 0px;}
.chart-item + .chart-item {margin-top: 10px;}
.chartbox {
height: 400px;
overflow: overlay;
border: 1px solid #ddd;
}
.ant-table-tbody>tr>td, .ant-table-thead>tr>th {
padding: 8px!important;
}
.table-title {
top: 10px;
right: auto;
bottom: auto;
left: 10px;
width: auto;
height: auto;
margin: 0px 0px 10px 10px;
font-size: 18px;
font-weight: bold;
text-align: left;
}
#subNavbar .nav li.active a {display: none;}
#mainContent .cell {padding: 11px;}
#mainContent .panel {border: 0;}
#mainContent .chart-item.main-row x-vue-echarts {max-height: 460px;}
#mainContent .chart-item.main-row .ant-table-wrapper {max-height: 398px; overflow-y: overlay !important;border: 1px solid #e8e8e8; border-right: 0;}
#mainContent .chart-item.main-row .ant-table-bordered .ant-table-body>table {border: 0;}
#mainContent .chart-item.main-row .ant-table-bordered .ant-table-body>table tr:last-child td {border-bottom: 0;}
.echart-content {width: 100%; min-height: 500px;}
.filterBox{display: flex; margin-bottom: 20px;}
.filter-items{display: flex; flex: 1; flex-wrap: wrap;}
.filter-item{padding: 0 16px 5px 0;}
.filter-item-grow{flex-grow: 1;}
.queryBtn{display: flex; align-items: center; padding-bottom: 5px;}
.filterBox .picker-selections{width: 128px; height: 32px; overflow: hidden; text-overflow: clip; white-space: nowrap;}
+56
View File
@@ -0,0 +1,56 @@
/**
* Ajax get chart data.
*
* @access public
* @return bool
*/
function ajaxGetChart(check = true, chart = DataStorage.chart, echart = window.echart)
{
var chartParams = JSON.parse(JSON.stringify(chart));
if(typeof DataStorage != 'undefined') chartParams.fieldSettings = JSON.parse(JSON.stringify(DataStorage.fieldSettings));
if(typeof DataStorage != 'undefined') chartParams.langs = JSON.parse(JSON.stringify(DataStorage.langs));
/* Redraw echart. */
/* 拿数据并重绘图表。*/
$.post(createLink('chart', 'ajaxGetChart'), chartParams, function(resp)
{
var data = JSON.parse(resp);
if(echart)
{
echart.clear();
echart.setOption(data, true);
$('.btn-export').removeClass('hidden');
}
});
}
/**
* Init picker.
*
* @access public
* @return void
*/
function initPicker($row, pickerName = 'picker-select')
{
$row.find('.' + pickerName).picker({'maxDropHeight': pickerHeight});
$row.find("." + pickerName).each(function(index)
{
if($(this).hasClass('required')) $(this).siblings("div .picker").addClass('required');
});
}
/**
* Init datepicker.
*
* @param object $obj
* @param function callback
* @access public
* @return void
*/
function initDatepicker($obj, callback)
{
$obj.find('.form-date').datepicker();
$obj.find('.form-datetime').datetimepicker();
if(typeof callback == 'function') callback($obj);
}
+215
View File
@@ -0,0 +1,215 @@
$(function()
{
initCheckBox();
initQueryBtn();
$('#exportchart').modalTrigger();
chartMap = new Map();
if(charts.length > 0)
{
charts.forEach(function(chart)
{
var echartDom = $('#chartDraw' + chart.currentGroup + chart.id).get(0);
var echart = echarts.init(echartDom);
ajaxGetChart(false, chart, echart);
renderFilters(chart);
chartMap.set(chart.currentGroup + chart.id, chart);
});
}
calcPreviewGrowFilter();
$('body').resize(() => {calcPreviewGrowFilter(true);});
$('[data-toggle="tooltip"]').tooltip();
})
/**
* Init check box.
*
* @access public
* @return void
*/
function initCheckBox()
{
/* Use parent checked prop set all child. */
$('input[data-type="parent"]').click(function()
{
$(this).parent().siblings('ul').find('input[data-type="child"]').prop('checked', $(this).prop('checked'));
});
$('input[data-type="child"]').click(function()
{
/* If child unchecked after click, set parent unchecked. */
if(!$(this).prop('checked'))
{
$(this).parentsUntil('#chartGroups', 'li').find('div').children('input[data-type="parent"]').prop('checked', false);
}
/* If child checked after click, if all child checked, set parent checked. */
else
{
if($(this).closest('ul').find('input[data-type="child"]').length >= 1)
{
var siblings_checked = $(this).closest('ul').find('input[data-type="child"]:checked').length;
var siblings_total = $(this).closest('ul').find('input[data-type="child"]').length;
if(siblings_checked == siblings_total)
{
$(this).parentsUntil('#chartGroups', 'li').find('div').children('input[data-type="parent"]').prop('checked', true);
}
}
}
});
/* Use click to trigger event. */
charts.forEach(function(item)
{
$("#chart_" + item.currentGroup + '_' + item.id).click();
});
}
/**
* Init query button.
*
* @access public
* @return void
*/
function initQueryBtn()
{
$('.btn-query').click(function()
{
var chartID = $(this).attr('data-chart');
var chartInfo = chartMap.get(chartID);
chartInfo.searchFilters = JSON.parse(JSON.stringify(chartInfo.filters));
// Foreach filters and set current value in searchFilters. */
$('#filterItems' + chartID + ' .filter-items').children().each(function(index)
{
var $child = $(this);
var filter = chartInfo.searchFilters[index];
var type = filter.type;
var value = null;
if(type == 'input' || type == 'select')
{
var value = $child.find('#default').val();
chartInfo.searchFilters[index].default = value;
}
else if(type == 'date' || type == 'datetime')
{
var begin = $child.find('input').first().val();
var end = $child.find('input').last().val();
var value = {"begin":begin, "end":end};
chartInfo.searchFilters[index].default = value;
}
else if(type == 'condition')
{
var operator = $child.find('#operator').data('zui.picker').getValue();
var value = $child.find('#value').val();
chartInfo.searchFilters[index].operator = operator;
chartInfo.searchFilters[index].value = value;
}
});
//* Reload echart. */
var echartDom = $('#chartDraw' + chartID).get(0);
var echartInfo = echarts.init(echartDom);
ajaxGetChart(false, chartInfo, echartInfo);
});
}
function calcPreviewGrowFilter(resize = false)
{
if(charts.length <= 0) return;
charts.forEach(function(chart)
{
/* When body resize, resize echarts. */
if(resize)
{
var echartDom = $('#chartDraw' + chart.currentGroup + chart.id).get(0);
var echart = echarts.init(echartDom);
echart.resize();
}
var $filterItems = $('#filterItems' + chart.currentGroup + chart.id + ' .filter-items');
/* When refreshing this page, ZenTao load this page twice, when the first load isn't complete, jump back to index and load the second time,
the first load can't calc filter width, can't get the element using jQuery at first load. */
var hasInit = true;
chart.filters.forEach(function(filter, index)
{
var nowItem = '.filter-item-' + index;
var $titleSpan = $filterItems.find(nowItem).find('.input-group-addon').first();
if(!$titleSpan.length) hasInit = false;
});
if(!hasInit) return;
var domWidth = $filterItems[0].getBoundingClientRect().width;
var nowWidth = domWidth;
var nowCount = 0;
var canGrowTotal = 0;
chart.filters.forEach(function(filter, index)
{
var nowItem = '.filter-item-' + index;
var leftPadding = parseInt($filterItems.find(nowItem).css('padding-left'));
var rightPadding = parseInt($filterItems.find(nowItem).css('padding-right'));
var spanWidth = $filterItems.find(nowItem).find('.input-group-addon').first()[0].getBoundingClientRect().width;
var filterWidth = ((filter.type == 'input' || filter.type == 'select') ? WIDTH_INPUT : WIDTH_DATE) + (spanWidth + leftPadding + rightPadding);
/* Clear the flex-basis and set flex-basic again. */
$filterItems.find(nowItem).css('flex-basis', '');
$filterItems.find(nowItem).css('flex-basis', filterWidth);
if(nowWidth - filterWidth >= 0)
{
nowWidth -= filterWidth;
nowCount ++;
}
else
{
canGrowTotal += nowCount;
nowWidth = domWidth - filterWidth;
nowCount = 1;
}
});
/* Clear all filter filter-item-grow and add class to support grow element. */
$filterItems.children().removeClass('filter-item-grow');
chart.filters.forEach(function(filter, index)
{
var nowItem = '.filter-item-' + index;
if(canGrowTotal >= index + 1) $filterItems.find(nowItem).addClass('filter-item-grow');
});
});
}
function renderFilters(chart)
{
if(chart.filters.length == 0) return;
var fieldNames = {};
Object.keys(chart.fieldSettings).forEach(function(key){fieldNames[key] = chart.fieldSettings[key].name;});
$.post(createLink('chart', 'ajaxGetFilterForm', 'chartID=' + chart.id), {fieldList: fieldNames, fieldSettings: chart.fieldSettings, filters: chart.filters, langs: chart.langs}, function(resp)
{
resp = JSON.parse(resp);
chart.filters.forEach(function(filter, index)
{
var $filterItems = $('#filterItems' + chart.currentGroup + chart.id + ' .filter-items');
$filterItems.append(renderFilterItem(filter, resp, index));
});
});
}
function renderFilterItem(filter, resp, index, step)
{
var tpl = $('#filterItemTpl').html();
var data =
{
index: index,
name: filter.name,
search: resp[index].item
};
var html = $($.zui.formatString(tpl, data))
initPicker(html);
initDatepicker(html);
return html;
}
+33
View File
@@ -0,0 +1,33 @@
<?php
$lang->chart->preview = 'View Chart';
$lang->chart->query = 'Query';
$lang->chart->toDesign = 'To Design';
$lang->chart->group = 'Group';
$lang->chart->field = 'Field';
$lang->chart->agg = 'Aggregate';
$lang->chart->chooseField = 'Choose field';
$lang->chart->aggType = 'Aggregate type';
$lang->chart->other = 'Other';
$lang->chart->unlimited = 'Unlimited';
$lang->chart->colon = 'To';
$lang->chart->fieldTypeList = array();
$lang->chart->fieldTypeList['input'] = 'Text';
$lang->chart->fieldTypeList['date'] = 'Date';
$lang->chart->fieldTypeList['datetime'] = 'Time';
$lang->chart->fieldTypeList['select'] = 'Dropdown';
//$lang->chart->fieldTypeList['condition'] = 'Condition';
$lang->chart->groupWeek = 'Week %s,%s';
$lang->chart->noChart = 'No Chart';
$lang->chart->noChartSelected = 'Please select one chart.';
$lang->chart->aggList = array();
$lang->chart->aggList['count'] = 'Count';
$lang->chart->aggList['distinct'] = 'Count after distinct';
$lang->chart->aggList['avg'] = 'AVG';
$lang->chart->aggList['sum'] = 'SUM';
$lang->chart->aggList['max'] = 'MAX';
$lang->chart->aggList['min'] = 'MIN';
+33
View File
@@ -0,0 +1,33 @@
<?php
$lang->chart->preview = 'View Chart';
$lang->chart->query = 'Query';
$lang->chart->toDesign = 'To Design';
$lang->chart->group = 'Group';
$lang->chart->field = 'Field';
$lang->chart->agg = 'Aggregate';
$lang->chart->chooseField = 'Choose field';
$lang->chart->aggType = 'Aggregate type';
$lang->chart->other = 'Other';
$lang->chart->unlimited = 'Unlimited';
$lang->chart->colon = 'To';
$lang->chart->fieldTypeList = array();
$lang->chart->fieldTypeList['input'] = 'Text';
$lang->chart->fieldTypeList['date'] = 'Date';
$lang->chart->fieldTypeList['datetime'] = 'Time';
$lang->chart->fieldTypeList['select'] = 'Dropdown';
//$lang->chart->fieldTypeList['condition'] = 'Condition';
$lang->chart->groupWeek = 'Week %s,%s';
$lang->chart->noChart = 'No Chart';
$lang->chart->noChartSelected = 'Please select one chart.';
$lang->chart->aggList = array();
$lang->chart->aggList['count'] = 'Count';
$lang->chart->aggList['distinct'] = 'Count after distinct';
$lang->chart->aggList['avg'] = 'AVG';
$lang->chart->aggList['sum'] = 'SUM';
$lang->chart->aggList['max'] = 'MAX';
$lang->chart->aggList['min'] = 'MIN';
+33
View File
@@ -0,0 +1,33 @@
<?php
$lang->chart->preview = 'View Chart';
$lang->chart->query = 'Query';
$lang->chart->toDesign = 'To Design';
$lang->chart->group = 'Group';
$lang->chart->field = 'Field';
$lang->chart->agg = 'Aggregate';
$lang->chart->chooseField = 'Choose field';
$lang->chart->aggType = 'Aggregate type';
$lang->chart->other = 'Other';
$lang->chart->unlimited = 'Unlimited';
$lang->chart->colon = 'To';
$lang->chart->fieldTypeList = array();
$lang->chart->fieldTypeList['input'] = 'Text';
$lang->chart->fieldTypeList['date'] = 'Date';
$lang->chart->fieldTypeList['datetime'] = 'Time';
$lang->chart->fieldTypeList['select'] = 'Dropdown';
//$lang->chart->fieldTypeList['condition'] = 'Condition';
$lang->chart->groupWeek = 'Week %s,%s';
$lang->chart->noChart = 'No Chart';
$lang->chart->noChartSelected = 'Please select one chart.';
$lang->chart->aggList = array();
$lang->chart->aggList['count'] = 'Count';
$lang->chart->aggList['distinct'] = 'Count after distinct';
$lang->chart->aggList['avg'] = 'AVG';
$lang->chart->aggList['sum'] = 'SUM';
$lang->chart->aggList['max'] = 'MAX';
$lang->chart->aggList['min'] = 'MIN';
+33
View File
@@ -0,0 +1,33 @@
<?php
$lang->chart->preview = '查看图表';
$lang->chart->query = '查询';
$lang->chart->toDesign = '进入设计';
$lang->chart->group = '所属分组';
$lang->chart->field = '关联字段';
$lang->chart->agg = '汇总';
$lang->chart->chooseField = '选择字段';
$lang->chart->aggType = '统计方式';
$lang->chart->other = '其他';
$lang->chart->unlimited = '不限';
$lang->chart->colon = '至';
$lang->chart->fieldTypeList = array();
$lang->chart->fieldTypeList['input'] = '文本框';
$lang->chart->fieldTypeList['date'] = '日期';
$lang->chart->fieldTypeList['datetime'] = '时间';
$lang->chart->fieldTypeList['select'] = '下拉菜单';
//$lang->chart->fieldTypeList['condition'] = '条件筛选';
$lang->chart->groupWeek = '%s年第%s周';
$lang->chart->noChart = '暂时没有图表';
$lang->chart->noChartSelected = '请选择至少一个图表。';
$lang->chart->aggList = array();
$lang->chart->aggList['count'] = '计数';
$lang->chart->aggList['distinct'] = '去重后计数';
$lang->chart->aggList['avg'] = '平均值';
$lang->chart->aggList['sum'] = '求和';
$lang->chart->aggList['max'] = '最大值';
$lang->chart->aggList['min'] = '最小值';
+627
View File
@@ -0,0 +1,627 @@
<?php
/**
* The model file of chart module of ZenTaoPMS.
*
* @copyright Copyright 2009-2015 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Chunsheng Wang <chunsheng@cnezsoft.com>
* @package chart
* @version $Id: model.php 5086 2013-07-10 02:25:22Z wyd621@gmail.com $
* @link http://www.zentao.net
*/
class chartModel extends model
{
/**
* Get first chart group id.
*
* @param int $dimensionID
* @access public
* @return int
*/
public function getFirstChartGroupID($dimensionID)
{
return $this->dao->select('id')->from(TABLE_MODULE)
->where('deleted')->eq('0')
->andWhere('type')->eq('chart')
->andWhere('root')->eq($dimensionID)
->andWhere('grade')->eq(1)
->orderBy('`order`')
->limit(1)
->fetch('id');
}
/**
* Get chart.
*
* @param int $chartID
* @access public
* @return object
*/
public function getByID($chartID)
{
$chart = $this->dao->select('*')->from(TABLE_CHART)->where('id')->eq($chartID)->fetch();
if(!$chart) return false;
if(!empty($chart->fields) and $chart->fields != 'null')
{
$chart->fieldSettings = json_decode($chart->fields);
$chart->fields = array();
foreach($chart->fieldSettings as $field => $settings) $chart->fields[] = $field;
}
else
{
$chart->fieldSettings = array();
}
if($chart->sql == null) $chart->sql = '';
if(!empty($chart->filters)) $chart->filters = json_decode($chart->filters, true);
return $this->processChart($chart);
}
/**
* Process sql and correct type.
*
* @param object $chart
* @access public
* @return object
*/
public function processChart($chart)
{
if(!empty($chart->sql)) $chart->sql = trim(str_replace(';', '', $chart->sql));
if(!empty($chart->settings)) $chart->settings = json_decode($chart->settings, true);
if(!empty($chart->settings) and is_array($chart->settings))
{
$firstSetting = current($chart->settings);
if(isset($firstSetting['type'])) $chart->type = $firstSetting['type'];
}
return $chart;
}
/**
* Get tree of charts and groups.
*
* @param int $groupID
* @param string $orderBy
* @access public
* @return array
*/
public function getPreviewCharts($groupID, $orderBy = 'id_desc')
{
if(!$groupID) return array('', array());
$currentGroup = $this->loadModel('tree')->getByID($groupID);
if(empty($currentGroup) || $currentGroup->grade != 1) return array('', array());
$groups = $this->dao->select('id, grade, name')->from(TABLE_MODULE)->where('deleted')->eq('0')->andWhere('path')->like("{$currentGroup->path}%")->orderBy('`order`')->fetchAll();
if(!$groups) return array('', array());
$chartGroups = array();
foreach($groups as $group)
{
$chartGroups[$group->id] = $this->dao->select('*')->from(TABLE_CHART)
->where('deleted')->eq(0)
->andWhere("FIND_IN_SET($group->id, `group`)")
->andWhere('stage')->ne('draft')
->orderBy($orderBy)
->fetchAll();
}
if(!$chartGroups) return array('', array());
$readyCharts = array();
foreach($chartGroups as $groupID => $chartGroup)
{
$charts = array();
foreach($chartGroup as $chart)
{
if($chart->stage != 'published') continue;
$charts[] = $chart;
}
if(!empty($charts)) $readyCharts[$groupID] = $charts;
}
$index = 1;
$chartTree = '';
$firstChart = null;
foreach($groups as $group)
{
if(!isset($readyCharts[$group->id])) continue;
if($group->grade == 2)
{
$class = $index == 1 ? 'open' : 'closed';
$chartTree .= "<li class='$class'><div class='checkbox-primary'><input type='checkbox' data-type='parent' name='groups[]' id='group{$group->id}' value='{$group->id}' title='{$group->name}'><label>{$group->name}</label></div><ul>";
}
$charts = $readyCharts[$group->id];
foreach($charts as $chart)
{
$chart->currentGroup = $group->id;
if(!$firstChart) $firstChart = $chart;
$chartTree .= "<li title='{$chart->name}'><div class='checkbox-primary checkbox-inline'><input type='checkbox' data-type='child' name='charts[]' id='chart_{$group->id}_{$chart->id}' value='{$group->id}_{$chart->id}' title='{$chart->name}' data-group='{$group->id}'><label for='chart_{$group->id}_{$chart->id}'></label></div><a>{$chart->name}</a></li>";
}
if($group->grade == 2) $chartTree .= '</ul></li>';
$index++;
}
if($chartTree) $chartTree = "<ul id='chartGroups' class='tree' data-ride='tree'>" . $chartTree . '</ul>';
$charts = array();
if($firstChart)
{
if(!empty($firstChart->settings)) $firstChart->settings = json_decode($firstChart->settings, true);
if(!empty($firstChart->filters)) $firstChart->filters = json_decode($firstChart->filters, true);
if(!empty($firstChart->fields) and $firstChart->fields != 'null')
{
$firstChart->fieldSettings = json_decode($firstChart->fields);
$firstChart->fields = array_keys(json_decode($firstChart->fields, true));
}
$charts[] = $firstChart;
}
return array($chartTree, $charts);
}
/**
* Gen radar.
*
* @param int $fields
* @param int $settings
* @param int $defaultSql
* @param int $filters
* @param array $langs
* @access public
* @return void
*/
public function genRadar($fields, $settings, $defaultSql, $filters, $langs = array())
{
list($group, $metrics, $aggs, $xLabels, $yStats) = $this->getMultiData($settings, $defaultSql, $filters);
$yDatas = array();
$max = 0;
foreach($yStats as $yStat)
{
$data = array();
foreach($xLabels as $xLabel)
{
$yStatXLabel = isset($yStat[$xLabel]) ? $yStat[$xLabel] : 0;
$data[] = $yStatXLabel;
}
if(max($yStat) > $max) $max = max($yStat);
$yDatas[] = $data;
}
$series = array();
$legend = new stdclass();
$series['type'] = 'radar';
$clientLang = $this->app->getClientLang();
foreach($yDatas as $index => $yData)
{
$fieldName = $fields[$metrics[$index]]['name'];
if(!empty($fields[$metrics[$index]]['object']) and !empty($fields[$metrics[$index]]['field']))
{
$relatedObject = $fields[$metrics[$index]]['object'];
$relatedField = $fields[$metrics[$index]]['field'];
$this->app->loadLang($relatedObject);
$fieldName = isset($this->lang->$relatedObject->$relatedField) ? $this->lang->$relatedObject->$relatedField : $fieldName;
}
if(isset($langs[$metrics[$index]]) and !empty($langs[$metrics[$index]][$clientLang])) $fieldName = $langs[$metrics[$index]][$clientLang];
$seriesName = $fieldName . '(' . $this->lang->chart->aggList[$aggs[$index]] . ')';
$series['data'][] = array('name' => $seriesName, 'value' => $yData);
}
$indicator = array();
$optionList = $this->getSysOptions($fields[$group]['type'], $fields[$group]['object'], $fields[$group]['field']);
foreach($xLabels as $xLabel)
{
$labelName = isset($optionList[$xLabel]) ? $optionList[$xLabel] : $xLabel;
$indicator[] = array('name' => $labelName, 'max' => $max);
}
$options = array('series' => $series, 'legend' => $legend, 'radar' => array('indicator' => $indicator), 'tooltip' => array('trigger' => 'item'));
return $options;
}
/**
* Gen pie.
*
* @param string $schema
* @param object $settings
* @param string $sql
* @param array $filters
* @access public
* @return array
*/
public function genPie($fields, $settings, $sql, $filters)
{
$group = isset($settings['group'][0]['field']) ? $settings['group'][0]['field'] : '';
$date = isset($settings['group'][0]['group']) ? zget($this->config->chart->dateConvert, $settings['group'][0]['group']) : '';
$metric = isset($settings['metric'][0]['field']) ? $settings['metric'][0]['field'] : '';
$agg = isset($settings['metric'][0]['valOrAgg']) ? $settings['metric'][0]['valOrAgg'] : '';
$defaultSql = str_replace(';', '', $sql);
$groupSql = $groupBySql = "tt.`$group`";
if(!empty($date))
{
$groupSql = $date == 'MONTH' ? "YEAR(tt.`$group`) as ttyear, $date(tt.`$group`) as ttgroup" : "$date(tt.`$group`) as $group";
$groupBySql = $date == 'MONTH' ? "YEAR(tt.`$group`), $date(tt.`$group`)" : "$date(tt.`$group`)";
}
if($agg == 'distinct')
{
$aggSQL = "count($agg tt.`$metric`) as `$metric`";
}
else
{
$aggSQL = "$agg(tt.`$metric`) as `$metric`";
}
$sql = "select $groupSql,$aggSQL from ($defaultSql) tt";
if(!empty($filters))
{
$wheres = array();
foreach($filters as $field => $filter)
{
$wheres[] = "$field {$filter['operator']} {$filter['value']}";
}
$whereStr = implode(' and ', $wheres);
$sql .= " where $whereStr";
}
$sql .= " group by $groupBySql";
$rows = $this->dao->query($sql)->fetchAll();
$stat = $this->processRows($rows, $date, $group, $metric);
$maxCount = 50;
if(empty($date)) arsort($stat);
$copyStat = $stat;
$other = array_sum(array_splice($copyStat, $maxCount));
$stat[$this->lang->chart->other] = $other;
if(empty($date)) arsort($stat);
$optionList = $this->getSysOptions($fields[$group]['type'], $fields[$group]['object'], $fields[$group]['field']);
$data = array();
foreach($stat as $name => $value)
{
if($value == 0) continue;
$value = round($value, 2);
$labelName = isset($optionList[$name]) ? $optionList[$name] : $name;
$data[] = array('name' => $labelName, 'value' => $value);
}
$label = array('show' => true, 'position' => 'outside', 'formatter' => '{b} {d}%');
$legend = new stdclass();
$legend->type = 'scroll';
$legend->orient = 'vertical';
$legend->right = 0;
$series[] = array('data' => $data, 'type' => 'pie', 'label' => $label);
$options = array('series' => $series, 'legend' => $legend, 'tooltip' => array('trigger' => 'item', 'formatter' => "{b}<br/> {c} ({d}%)"));
return $options;
}
/**
* Process rows.
*
* @param array $rows
* @param string $date
* @param string $group
* @param string $metric
* @access public
* @return array
*/
public function processRows($rows, $date, $group, $metric)
{
$stat = array();
foreach($rows as $row)
{
if(!empty($date) and $date == 'MONTH')
{
$stat[sprintf("%04d", $row->ttyear) . '-' . sprintf("%02d", $row->ttgroup)] = $row->$metric;
}
elseif(!empty($date) and $date == 'YEARWEEK')
{
$yearweek = sprintf("%06d", $row->$group);
$year = substr($yearweek, 0, strlen($yearweek) - 2);
$week = substr($yearweek, -2);
$weekIndex = in_array($this->app->getClientLang(), array('zh-cn', 'zh-tw')) ? sprintf($this->lang->chart->groupWeek, $year, $week) : sprintf($this->lang->chart->groupWeek, $week, $year);
$stat[$weekIndex] = $row->$metric;
}
elseif(!empty($date) and $date == 'YEAR')
{
$stat[sprintf("%04d", $row->$group)] = $row->$metric;
}
else
{
$stat[$row->$group] = $row->$metric;
}
}
return $stat;
}
/**
* Gen line.
*
* @param string $schema
* @param object $settings
* @param string $sql
* @param array $filters
* @param array $langs
* @access public
* @return array
*/
public function genLineChart($fields, $settings, $defaultSql, $filters, $langs = array())
{
list($group, $metrics, $aggs, $xLabels, $yStats) = $this->getMultiData($settings, $defaultSql, $filters);
$fieldType = $fields[$settings['xaxis'][0]['field']]['type'];
if($fieldType == 'date') sort($xLabels);
$yDatas = array();
foreach($xLabels as $xLabel)
{
foreach($yStats as $index => $yStat)
{
if(!isset($yDatas[$index])) $yDatas[$index] = array();
$yDatas[$index][] = isset($yStat[$xLabel]) ? $yStat[$xLabel] : 0;
}
}
$optionList = $this->getSysOptions($fields[$group]['type'], $fields[$group]['object'], $fields[$group]['field']);
foreach($xLabels as $index => $xLabel) $xLabels[$index] = isset($optionList[$xLabel]) ? $optionList[$xLabel] : $xLabel;
$xaxis = array('type' => 'category', 'data' => $xLabels);
$yaxis = array('type' => 'value');
$legend = new stdclass();
$series = array();
$clientLang = $this->app->getClientLang();
foreach($yDatas as $index => $yData)
{
$fieldName = $fields[$metrics[$index]]['name'];
if(!empty($fields[$metrics[$index]]['object']) and !empty($fields[$metrics[$index]]['field']))
{
$relatedObject = $fields[$metrics[$index]]['object'];
$relatedField = $fields[$metrics[$index]]['field'];
$this->app->loadLang($relatedObject);
$fieldName = isset($this->lang->$relatedObject->$relatedField) ? $this->lang->$relatedObject->$relatedField : $fieldName;
}
if(isset($langs[$metrics[$index]]) and !empty($langs[$metrics[$index]][$clientLang])) $fieldName = $langs[$metrics[$index]][$clientLang];
$seriesName = $fieldName . '(' . $this->lang->chart->aggList[$aggs[$index]] . ')';
$series[] = array('name' => $seriesName, 'data' => $yData, 'type' => 'line');
}
$options = array('series' => $series, 'legend' => $legend, 'xAxis' => $xaxis, 'yAxis' => $yaxis, 'tooltip' => array('trigger' => 'axis'));
return $options;
}
/**
* Gen cluBar.
*
* @param int $fields
* @param int $settings
* @param int $defaultSql
* @param int $filters
* @param int $stack
* @param array $langs
* @access public
* @return void
*/
public function genCluBar($fields, $settings, $defaultSql, $filters, $stack = '', $langs = array())
{
list($group, $metrics, $aggs, $xLabels, $yStats) = $this->getMultiData($settings, $defaultSql, $filters);
$yDatas = array();
foreach($yStats as $yStat)
{
$data = array();
foreach($xLabels as $xLabel)
{
$data[] = isset($yStat[$xLabel]) ? $yStat[$xLabel] : 0;
}
$yDatas[] = $data;
}
$optionList = $this->getSysOptions($fields[$group]['type'], $fields[$group]['object'], $fields[$group]['field']);
foreach($xLabels as $index => $xLabel) $xLabels[$index] = isset($optionList[$xLabel]) ? $optionList[$xLabel] : $xLabel;
$xaxis = array('type' => 'category', 'data' => $xLabels, 'axisLabel' => array('interval' => 0));
$yaxis = array('type' => 'value');
$legend = new stdclass();
/* Cluster bar X graphs and cluster bar Y graphs are really just x and y axes switched, so cluster bar Y $xaixs and $yaxis are swapped so that the method can be reused. */
/* 簇状柱形图和簇状条形图其实只是x轴和y轴换了换,所以交换一下簇状条形图 xAxis和yAxis即可,这样方法就可以复用了。*/
if(in_array($settings['type'], array('cluBarY', 'stackedBarY'))) list($xaxis, $yaxis) = array($yaxis, $xaxis);
$series = array();
$clientLang = $this->app->getClientLang();
foreach($yDatas as $index => $yData)
{
$fieldName = $fields[$metrics[$index]]['name'];
if(!empty($fields[$metrics[$index]]['object']) and !empty($fields[$metrics[$index]]['field']))
{
$relatedObject = $fields[$metrics[$index]]['object'];
$relatedField = $fields[$metrics[$index]]['field'];
$this->app->loadLang($relatedObject);
$fieldName = isset($this->lang->$relatedObject->$relatedField) ? $this->lang->$relatedObject->$relatedField : $fieldName;
}
if(isset($langs[$metrics[$index]]) and !empty($langs[$metrics[$index]][$clientLang])) $fieldName = $langs[$metrics[$index]][$clientLang];
$seriesName = $fieldName . '(' . $this->lang->chart->aggList[$aggs[$index]] . ')';
$series[] = array('name' => $seriesName, 'data' => $yData, 'type' => 'bar', 'stack' => $stack);
}
$options = array('series' => $series, 'legend' => $legend, 'xAxis' => $xaxis, 'yAxis' => $yaxis, 'tooltip' => array('trigger' => 'axis'));
return $options;
}
/**
* Get multi data.
*
* @param int $settings
* @param int $defaultSql
* @param int $filters
* @access public
* @return void
*/
public function getMultiData($settings, $defaultSql, $filters, $sort = false)
{
$group = isset($settings['xaxis'][0]['field']) ? $settings['xaxis'][0]['field'] : '';
$date = isset($settings['xaxis'][0]['group']) ? zget($this->config->chart->dateConvert, $settings['xaxis'][0]['group']) : '';
$metrics = array();
$aggs = array();
foreach($settings['yaxis'] as $yaxis)
{
$metrics[] = $yaxis['field'];
$aggs[] = $yaxis['valOrAgg'];
}
$yCount = count($metrics);
$xLabels = array();
$yStats = array();
for($i = 0; $i < $yCount; $i ++)
{
$metric = $metrics[$i];
$agg = $aggs[$i];
$groupSql = $groupBySql = "tt.`$group`";
if(!empty($date))
{
$groupSql = $date == 'MONTH' ? "YEAR(tt.`$group`) as ttyear, $date(tt.`$group`) as ttgroup" : "$date(tt.`$group`) as $group";
$groupBySql = $date == 'MONTH' ? "YEAR(tt.`$group`), $date(tt.`$group`)" : "$date(tt.`$group`)";
}
if($agg == 'distinct')
{
$aggSQL = "count($agg tt.`$metric`) as `$metric`";
}
else
{
$aggSQL = "$agg(tt.`$metric`) as `$metric`";
}
$sql = "select $groupSql,$aggSQL from ($defaultSql) tt";
if(!empty($filters))
{
$wheres = array();
foreach($filters as $field => $filter)
{
$wheres[] = "$field {$filter['operator']} {$filter['value']}";
}
$whereStr = implode(' and ', $wheres);
$sql .= " where $whereStr";
}
$sql .= " group by $groupBySql";
$rows = $this->dao->query($sql)->fetchAll();
$stat = $this->processRows($rows, $date, $group, $metric);
$maxCount = 50;
if($sort) arsort($stat);
$yStats[] = $stat;
$xLabels = array_merge($xLabels, array_keys($stat));
$xLabels = array_unique($xLabels);
}
return array($group, $metrics, $aggs, $xLabels, $yStats);
}
/**
* Adjust the action is clickable.
*
* @param object $chart
* @param string $action
* @static
* @access public
* @return bool
*/
public static function isClickable($chart, $action)
{
return true;
}
/**
* Get sys options.
*
* @param string $type
* @access public
* @return array
*/
public function getSysOptions($type, $object = '', $field = '')
{
$options = array('' => '');
switch($type)
{
case 'user':
$options = $this->loadModel('user')->getPairs();
break;
case 'product':
$options = $this->loadModel('product')->getPairs();
break;
case 'project':
$options = $this->loadModel('project')->getPairsByProgram();
break;
case 'execution':
$options = $this->loadModel('execution')->getPairs();
break;
case 'dept':
$options = $this->loadModel('dept')->getOptionMenu(0);
break;
case 'option':
if($field)
{
$path = $this->app->getModuleRoot() . 'dataview' . DS . 'table' . DS . "$object.php";
include $path;
$options = $schema->fields[$field]['options'];
}
break;
case 'object':
if($field)
{
$table = zget($this->config->objectTables, $object);
$options = $this->dao->select("id, {$field}")->from($table)->fetchPairs();
}
break;
/*case 'string':
if($field)
{
$table = zget($this->config->objectTables, $object);
$options = $this->dao->select("{$field}, {$field}")->from($table)->fetchPairs();
}
break;
*/
}
return $options;
}
}
+113
View File
@@ -0,0 +1,113 @@
<?php
/**
* The preview view file of chart module of ZenTaoPMS.
*
* @copyright Copyright 2009-2022 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Gang Liu <liugang@easycorp.ltd>
* @package chart
* @version $Id$
* @link http://www.zentao.net
*/
?>
<?php include $app->getModuleRoot() . 'common/view/header.html.php';?>
<?php js::import($jsRoot . 'moment/moment.min.js');?>
<?php js::import($jsRoot . 'echarts/echarts.common.min.js');?>
<?php js::set('groupID', isset($group->id) ? $group->id : 0);?>
<?php js::set('charts', $charts);?>
<?php js::set('noChartSelected', $lang->chart->noChartSelected);?>
<?php js::set('chartLang', $lang->chart);?>
<?php js::set('WIDTH_INPUT', $config->chart->widthInput);?>
<?php js::set('WIDTH_DATE', $config->chart->widthDate);?>
<?php js::set('pickerHeight', $config->bi->pickerHeight);?>
<div id='mainMenu' class='clearfix main-position'>
<div class='btn-toolBar pull-left parent-position'>
<?php
foreach($groups as $groupID => $groupName)
{
if(!$groupID) continue;
$activeClass = $groupID == $group->id ? 'btn-active-text' : '';
echo html::a(inlink('preview', "dimensionID={$dimensionID}&groupID={$groupID}"), $groupName, '', "class='btn btn-link {$activeClass}' id='{$groupID}Tab'");
}
?>
</div>
<?php if($this->config->edition == 'biz' or $this->config->edition == 'max'):?>
<div class='btn-toolbar pull-right child-position'>
<?php common::printLink('chart', 'exportChart', '', "<i class='icon icon-export muted'> </i> " . $lang->export, '', "class='btn btn-link btn-export' id='exportchart'");?>
<?php common::printLink('chart', 'browse', '', $lang->chart->toDesign, '', "class='btn btn-primary '");?>
</div>
<?php endif;?>
</div>
<div id="mainContent" class='main-row'>
<div class='side-col col-lg'>
<div class='panel'>
<div class='panel-heading'>
<div class='panel-title'><?php echo isset($group->name) ? $group->name : '';?></div>
</div>
<div class='panel-body'>
<?php if(!$chartTree):?>
<hr class="space">
<div class="text-center text-muted">
<?php echo $lang->chart->noChart;?>
</div>
<hr class="space">
<?php elseif($chartTree):?>
<form method='post'>
<?php echo $chartTree;?>
<div class='btn-toolbar'>
<?php echo html::selectAll();?>
<?php echo html::submitButton($lang->chart->preview, '', 'btn btn-primary');?>
</div>
</form>
<?php endif;?>
</div>
</div>
</div>
<div class='main-col'>
<div class='cell'>
<?php if(!$chartTree):?>
<hr class="space">
<div class="text-center text-muted">
<?php echo $lang->chart->noChart;?>
</div>
<hr class="space">
<?php else:?>
<div class='btn-toolbar pull-right'>
</div>
<?php foreach($charts as $chart):?>
<div class='panel'>
<div class='panel-heading'>
<div class='panel-title'>
<?php echo $chart->name;?>
<?php if(!empty($chart->desc)):?>
<a data-toggle='tooltip' data-placement='auto' title=<?php echo $chart->desc;?>><i class='icon-help'></i></a>
<?php endif;?>
</div>
</div>
<div class='panel-body'>
<div id="filterItems<?php echo $chart->currentGroup;?><?php echo $chart->id;?>" class='filterBox'>
<div class='filter-items'></div>
<?php if(!empty($chart->filters)):?>
<div class='queryBtn'><?php echo html::submitButton($lang->chart->query, "data-chart={$chart->currentGroup}{$chart->id}", 'btn btn-primary btn-query');?></div>
<?php endif;?>
</div>
<div id="chartDraw<?php echo $chart->currentGroup;?><?php echo $chart->id;?>" data-group="<?php echo $chart->currentGroup;?>" data-id="<?php echo $chart->id;?>" class='echart-content'></div>
</div>
</div>
<?php endforeach;?>
<?php endif;?>
</div>
</div>
</div>
<?php include $app->getModuleRoot() . 'common/view/footer.html.php';?>
<template id='filterItemTpl'>
<div class='filter-item filter-item-{index}'>
<div class='input-group'>
<span class='input-group-addon field-name'>{name}</span>
{search}
</div>
</div>
</template>
+1
View File
@@ -44,6 +44,7 @@ $lang->user = new stdclass();
$lang->screen = new stdclass();
$lang->report = new stdclass();
$lang->pivot = new stdclass();
$lang->chart = new stdclass();
$lang->repo = new stdclass();
$lang->jenkins = new stdclass();
$lang->gitlab = new stdclass();
+1
View File
@@ -177,6 +177,7 @@ $lang->repo->codeRepo = 'Code Repo';
$lang->screen->common = 'Screen';
$lang->report->common = 'BI';
$lang->pivot->common = 'Pivot Table';
$lang->chart->common = 'Chart';
$lang->system->common = 'System';
$lang->admin->common = 'Admin';
$lang->story->common = 'Story';
+1
View File
@@ -177,6 +177,7 @@ $lang->repo->codeRepo = 'Code Repo';
$lang->screen->common = 'Screen';
$lang->report->common = 'BI';
$lang->pivot->common = 'Pivot Table';
$lang->chart->common = 'Chart';
$lang->system->common = 'System';
$lang->admin->common = 'Admin';
$lang->story->common = 'Story';
+1
View File
@@ -177,6 +177,7 @@ $lang->repo->codeRepo = 'Code Repo';
$lang->screen->common = 'Screen';
$lang->report->common = 'BI';
$lang->pivot->common = 'Pivot Table';
$lang->chart->common = 'Chart';
$lang->system->common = 'System';
$lang->admin->common = 'Admin';
$lang->story->common = 'Story';
+3
View File
@@ -519,10 +519,12 @@ $lang->doc->menuOrder[30] = 'custom';
$lang->report->menu = new stdclass();
$lang->report->menu->screen = array('link' => "{$lang->screen->common}|screen|browse");
$lang->report->menu->pivot = array('link' => "{$lang->pivot->common}|pivot|preview");
$lang->report->menu->chart = array('link' => "{$lang->chart->common}|chart|preview");
/* Report menu order. */
$lang->report->menuOrder[5] = 'screen';
$lang->report->menuOrder[10] = 'pivot';
$lang->report->menuOrder[15] = 'chart';
/* Company menu.*/
$lang->company->menu = new stdclass();
@@ -611,6 +613,7 @@ $lang->navGroup->api = 'doc';
$lang->navGroup->screen = 'report';
$lang->navGroup->pivot = 'report';
$lang->navGroup->chart = 'report';
$lang->navGroup->qa = 'qa';
$lang->navGroup->bug = 'qa';
+1
View File
@@ -177,6 +177,7 @@ $lang->repo->codeRepo = '代码库';
$lang->screen->common = '大屏';
$lang->report->common = 'BI';
$lang->pivot->common = '透视表';
$lang->chart->common = '图表';
$lang->system->common = '组织';
$lang->admin->common = '后台';
$lang->story->common = $lang->SRCommon;
+3
View File
@@ -0,0 +1,3 @@
<?php
$lang->dataview->id = 'ID';
$lang->dataview->name = 'Name';
+3
View File
@@ -0,0 +1,3 @@
<?php
$lang->dataview->id = 'ID';
$lang->dataview->name = 'Name';
+3
View File
@@ -0,0 +1,3 @@
<?php
$lang->dataview->id = 'ID';
$lang->dataview->name = 'Name';
+3
View File
@@ -0,0 +1,3 @@
<?php
$lang->dataview->id = '编号';
$lang->dataview->name = '名称';
+63
View File
@@ -0,0 +1,63 @@
<?php
$this->app->loadLang('bug');
$this->app->loadLang('product');
$this->app->loadLang('story');
$this->app->loadLang('project');
$this->app->loadLang('tree');
$schema = new stdclass();
$schema->primaryTable = 'bug';
$schema->tables = array();
$schema->tables['bug'] = 'zt_bug';
$schema->tables['product'] = 'zt_product';
$schema->tables['story'] = 'zt_story';
$schema->tables['productline'] = 'zt_module';
$schema->tables['program'] = 'zt_project';
$schema->tables['project'] = 'zt_project';
$schema->tables['bugmodule'] = 'zt_module';
$schema->joins = array();
$schema->joins['product'] = 'product.id = bug.product';
$schema->joins['story'] = 'story.id = bug.story';
$schema->joins['productline'] = 'productline.id = product.line';
$schema->joins['program'] = 'program.id = product.program';
$schema->joins['project'] = 'project.id = bug.project';
$schema->joins['bugmodule'] = 'bugmodule.id = bug.module';
$schema->fields = array();
$schema->fields['id'] = array('type' => 'number', 'name' => $this->lang->bug->id);
$schema->fields['title'] = array('type' => 'string', 'name' => $this->lang->bug->title);
$schema->fields['steps'] = array('type' => 'text', 'name' => $this->lang->bug->steps);
$schema->fields['status'] = array('type' => 'option', 'name' => $this->lang->bug->status, 'options' => $this->lang->bug->statusList);
$schema->fields['confirmed'] = array('type' => 'option', 'name' => $this->lang->bug->confirmed, 'options' => $this->lang->bug->confirmedList);
$schema->fields['severity'] = array('type' => 'option', 'name' => $this->lang->bug->severity, 'options' => $this->lang->bug->severityList);
$schema->fields['product'] = array('type' => 'object', 'name' => $this->lang->bug->product, 'object' => 'product', 'show' => 'product.name');
$schema->fields['project'] = array('type' => 'object', 'name' => $this->lang->bug->project, 'object' => 'project', 'show' => 'project.name');
$schema->fields['bugmodule'] = array('type' => 'object', 'name' => $this->lang->bug->module, 'object' => 'bugmodule', 'show' => 'bugmodule.name');
$schema->fields['story'] = array('type' => 'object', 'name' => $this->lang->story->common, 'object' => 'story', 'show' => 'story.title');
$schema->fields['pri'] = array('type' => 'option', 'name' => $this->lang->bug->pri, 'options' => $this->lang->bug->priList);
$schema->fields['openedBy'] = array('type' => 'user', 'name' => $this->lang->bug->openedBy);
$schema->fields['openedDate'] = array('type' => 'date', 'name' => $this->lang->bug->openedDate);
$schema->fields['resolvedBy'] = array('type' => 'user', 'name' => $this->lang->bug->resolvedBy);
$schema->fields['resolution'] = array('type' => 'option', 'name' => $this->lang->bug->resolution, 'options' => $this->lang->bug->resolutionList);
$schema->fields['resolvedDate'] = array('type' => 'date', 'name' => $this->lang->bug->resolvedDate);
$schema->objects = array();
$schema->objects['story'] = array();
$schema->objects['story']['id'] = array('type' => 'number', 'name' => $this->lang->story->id);
$schema->objects['story']['title'] = array('type' => 'string', 'name' => $this->lang->story->common);
$schema->objects['product'] = array();
$schema->objects['product']['id'] = array('type' => 'number', 'name' => $this->lang->product->id);
$schema->objects['product']['name'] = array('type' => 'string', 'name' => $this->lang->product->common);
$schema->objects['project'] = array();
$schema->objects['project']['id'] = array('type' => 'number', 'name' => $this->lang->project->id);
$schema->objects['project']['name'] = array('type' => 'string', 'name' => $this->lang->project->common);
$schema->objects['bugmodule'] = array();
$schema->objects['bugmodule']['id'] = array('type' => 'number', 'name' => $this->lang->bug->id);
$schema->objects['bugmodule']['name'] = array('type' => 'string', 'name' => $this->lang->tree->module);
+92
View File
@@ -0,0 +1,92 @@
<?php
$this->app->loadLang('bug');
$this->app->loadLang('product');
$this->app->loadLang('testtask');
$this->app->loadLang('build');
$this->app->loadLang('execution');
$this->app->loadLang('project');
$this->app->loadLang('tree');
$this->app->loadLang('dataview');
$schema = new stdclass();
$schema->primaryTable = 'bug';
$schema->tables = array();
$schema->tables['bug'] = 'zt_bug';
$schema->tables['product'] = 'zt_product';
$schema->tables['testtask'] = 'zt_testtask';
$schema->tables['testcase'] = 'zt_case';
$schema->tables['build'] = 'zt_build';
$schema->tables['execution'] = 'zt_project';
$schema->tables['project'] = 'zt_project';
$schema->tables['module'] = 'zt_module';
$schema->tables['casemodule'] = 'zt_module';
$schema->joins = array();
$schema->joins['product'] = 'product.id = bug.product';
$schema->joins['testtask'] = 'testtask.id = bug.testtask';
$schema->joins['build'] = 'build.id = testtask.build';
$schema->joins['execution'] = 'execution.id = build.execution';
$schema->joins['project'] = 'project.id = build.project';
$schema->joins['module'] = 'module.id = bug.module';
$schema->joins['testcase'] = 'testcase.id = bug.case';
$schema->joins['casemodule'] = 'casemodule.id = testcase.module';
$schema->fields = array();
$schema->fields['id'] = array('type' => 'number', 'name' => $this->lang->bug->id);
$schema->fields['title'] = array('type' => 'string', 'name' => $this->lang->bug->title);
$schema->fields['steps'] = array('type' => 'text', 'name' => $this->lang->bug->steps);
$schema->fields['status'] = array('type' => 'option', 'name' => $this->lang->bug->status, 'options' => $this->lang->bug->statusList);
$schema->fields['confirmed'] = array('type' => 'option', 'name' => $this->lang->bug->confirmed, 'options' => $this->lang->bug->confirmedList);
$schema->fields['severity'] = array('type' => 'option', 'name' => $this->lang->bug->severity, 'options' => $this->lang->bug->severityList);
$schema->fields['product'] = array('type' => 'object', 'name' => $this->lang->bug->product, 'object' => 'product', 'show' => 'product.name');
$schema->fields['project'] = array('type' => 'object', 'name' => $this->lang->bug->project, 'object' => 'project', 'show' => 'project.name');
$schema->fields['build'] = array('type' => 'object', 'name' => $this->lang->build->common, 'object' => 'build', 'show' => 'build.name');
$schema->fields['module'] = array('type' => 'object', 'name' => $this->lang->bug->module, 'object' => 'module', 'show' => 'module.name');
$schema->fields['testtask'] = array('type' => 'object', 'name' => $this->lang->testtask->common, 'object' => 'testtask', 'show' => 'testtask.name');
$schema->fields['pri'] = array('type' => 'option', 'name' => $this->lang->bug->pri, 'options' => $this->lang->bug->priList);
$schema->fields['openedBy'] = array('type' => 'user', 'name' => $this->lang->bug->openedBy);
$schema->fields['openedDate'] = array('type' => 'datetime', 'name' => $this->lang->bug->openedDate);
$schema->fields['resolvedBy'] = array('type' => 'user', 'name' => $this->lang->bug->resolvedBy);
$schema->fields['resolution'] = array('type' => 'option', 'name' => $this->lang->bug->resolution, 'options' => $this->lang->bug->resolutionList);
$schema->fields['resolvedDate'] = array('type' => 'datetime', 'name' => $this->lang->bug->resolvedDate);
$schema->fields['casemodule'] = array('type' => 'object', 'name' => $this->lang->tree->module, 'object' => 'casemodule', 'show' => 'casemodule.name');
$schema->objects = array();
$schema->objects['product'] = array();
$schema->objects['product']['id'] = array('type' => 'number', 'name' => $this->lang->product->id);
$schema->objects['product']['name'] = array('type' => 'string', 'name' => $this->lang->product->common);
$schema->objects['testtask'] = array();
$schema->objects['testtask']['id'] = array('type' => 'number', 'name' => $this->lang->testtask->id);
$schema->objects['testtask']['name'] = array('type' => 'string', 'name' => $this->lang->testtask->common);
$schema->objects['build'] = array();
$schema->objects['build']['id'] = array('type' => 'number', 'name' => $this->lang->build->id);
$schema->objects['build']['name'] = array('type' => 'string', 'name' => $this->lang->build->common);
$schema->objects['execution'] = array();
$schema->objects['execution']['id'] = array('type' => 'number', 'name' => $this->lang->dataview->id);
$schema->objects['execution']['name'] = array('type' => 'string', 'name' => $this->lang->execution->common);
$schema->objects['project'] = array();
$schema->objects['project']['id'] = array('type' => 'number', 'name' => $this->lang->project->id);
$schema->objects['project']['name'] = array('type' => 'string', 'name' => $this->lang->project->common);
$schema->objects['build'] = array();
$schema->objects['build']['id'] = array('type' => 'number', 'name' => $this->lang->build->id);
$schema->objects['build']['name'] = array('type' => 'string', 'name' => $this->lang->build->common);
$schema->objects['module'] = array();
$schema->objects['module']['id'] = array('type' => 'number', 'name' => $this->lang->dataview->id);
$schema->objects['module']['name'] = array('type' => 'string', 'name' => $this->lang->tree->module);
$schema->objects['testcase'] = array();
$schema->objects['testcase']['id'] = array('type' => 'number', 'name' => $this->lang->dataview->id);
$schema->objects['testcase']['title'] = array('type' => 'string', 'name' => $this->lang->testcase->common);
$schema->objects['casemodule'] = array();
$schema->objects['casemodule']['id'] = array('type' => 'number', 'name' => $this->lang->dataview->id);
$schema->objects['casemodule']['name'] = array('type' => 'string', 'name' => $this->lang->dataview->name);
+45
View File
@@ -0,0 +1,45 @@
<?php
$this->app->loadLang('product');
$this->app->loadLang('project');
$this->app->loadLang('execution');
$this->app->loadLang('build');
$schema = new stdclass();
$schema->primaryTable = 'build';
$schema->tables = array();
$schema->tables['product'] = 'zt_product';
$schema->tables['project'] = 'zt_project';
$schema->tables['execution'] = 'zt_project';
$schema->tables['build'] = 'zt_build';
$schema->joins = array();
$schema->joins['product'] = 'product.id = build.product';
$schema->joins['project'] = 'project.id = build.project';
$schema->joins['execution'] = 'execution.id = build.execution';
$schema->fields = array();
$schema->fields['product'] = array('type' => 'object', 'name' => $this->lang->build->product, 'object' => 'product', 'show' => 'product.name');
$schema->fields['project'] = array('type' => 'object', 'name' => $this->lang->build->project, 'object' => 'project', 'show' => 'project.name');
$schema->fields['execution'] = array('type' => 'object', 'name' => $this->lang->build->execution, 'object' => 'execution', 'show' => 'execution.name');
$schema->fields['name'] = array('type' => 'string', 'name' => $this->lang->build->name);
$schema->fields['builder'] = array('type' => 'user', 'name' => $this->lang->build->builder);
$schema->fields['stories'] = array('type' => 'string', 'name' => $this->lang->build->stories);
$schema->fields['bugs'] = array('type' => 'string', 'name' => $this->lang->build->bugs);
$schema->fields['date'] = array('type' => 'date', 'name' => $this->lang->build->date);
$schema->fields['desc'] = array('type' => 'string', 'name' => $this->lang->build->desc);
$schema->objects = array();
$schema->objects['product'] = array();
$schema->objects['product']['id'] = array('type' => 'number', 'name' => $this->lang->product->id);
$schema->objects['product']['name'] = array('type' => 'string', 'name' => $this->lang->product->name);
$schema->objects['project'] = array();
$schema->objects['project']['id'] = array('type' => 'number', 'name' => $this->lang->project->id);
$schema->objects['project']['name'] = array('type' => 'string', 'name' => $this->lang->project->name);
$schema->objects['execution'] = array();
$schema->objects['execution']['id'] = array('type' => 'number', 'name' => $this->lang->execution->id);
$schema->objects['execution']['name'] = array('type' => 'string', 'name' => $this->lang->execution->name);
+18
View File
@@ -0,0 +1,18 @@
<?php
$this->app->loadLang('tree');
$this->app->loadLang('dataview');
$schema = new stdclass();
$schema->primaryTable = 'casemodule';
$schema->tables = array();
$schema->tables['casemodule'] = 'zt_module';
$schema->joins = array();
$schema->fields = array();
$schema->fields['id'] = array('type' => 'number', 'name' => $this->lang->dataview->id);
$schema->fields['name'] = array('type' => 'string', 'name' => $this->lang->tree->module);
$schema->objects = array();
+30
View File
@@ -0,0 +1,30 @@
<?php
$this->app->loadLang('testcase');
$casestepLang = new stdclass();
$casestepLang->type = '步骤类型';
$casestepLang->typeList['step'] = '步骤';
$casestepLang->typeList['group'] = '分组';
$schema = new stdclass();
$schema->primaryTable = 'casestep';
$schema->tables = array();
$schema->tables['casestep'] = 'zt_casestep';
$schema->tables['testcase'] = 'zt_case';
$schema->joins = array();
$schema->joins['testcase'] = 'testcase.id = casestep.`case`';
$schema->fields = array();
$schema->fields['case'] = array('type' => 'object', 'name' => $this->lang->testcase->common, 'object' => 'testcase', 'show' => 'testcase.title');
$schema->fields['type'] = array('type' => 'option', 'name' => $casestepLang->type, 'options' => $casestepLang->typeList);
$schema->fields['desc'] = array('type' => 'string', 'name' => $this->lang->testcase->desc);
$schema->fields['expect'] = array('type' => 'string', 'name' => $this->lang->testcase->expect);
$schema->fields['version'] = array('type' => 'number', 'name' => $this->lang->testcase->version);
$schema->objects = array();
$schema->objects['testcase'] = array();
$schema->objects['testcase']['id'] = array('type' => 'number', 'name' => $this->lang->testcase->id);
$schema->objects['testcase']['title'] = array('type' => 'string', 'name' => $this->lang->testcase->title);
+37
View File
@@ -0,0 +1,37 @@
<?php
$this->app->loadLang('execution');
$this->app->loadLang('project');
$this->app->loadLang('product');
$schema = new stdclass();
$schema->primaryTable = 'execution';
$schema->tables = array();
$schema->tables['project'] = 'zt_project';
$schema->tables['execution'] = 'zt_project';
$schema->joins = array();
$schema->joins['project'] = 'execution.project = project.id';
$schema->fields = array();
$schema->fields['project'] = array('type' => 'object', 'name' => $this->lang->project->name, 'object' => 'project', 'show' => 'project.name');
$schema->fields['name'] = array('type' => 'string', 'name' => $this->lang->execution->name);
$schema->fields['code'] = array('type' => 'string', 'name' => $this->lang->execution->code);
$schema->fields['type'] = array('type' => 'option', 'name' => $this->lang->execution->type, 'options' => $this->lang->execution->typeList);
$schema->fields['status'] = array('type' => 'option', 'name' => $this->lang->execution->status, 'options' => $this->lang->execution->statusList);
$schema->fields['desc'] = array('type' => 'string', 'name' => $this->lang->execution->desc);
$schema->fields['begin'] = array('type' => 'date', 'name' => $this->lang->execution->begin);
$schema->fields['end'] = array('type' => 'date', 'name' => $this->lang->execution->end);
$schema->fields['PO'] = array('type' => 'user', 'name' => $this->lang->product->PO);
$schema->fields['PM'] = array('type' => 'user', 'name' => $this->lang->execution->PM);
$schema->fields['QD'] = array('type' => 'user', 'name' => $this->lang->execution->QD);
$schema->fields['RD'] = array('type' => 'user', 'name' => $this->lang->execution->RD);
$schema->fields['openedBy'] = array('type' => 'user', 'name' => $this->lang->execution->openedBy);
$schema->fields['openedDate'] = array('type' => 'date', 'name' => $this->lang->execution->openedDate);
$schema->objects = array();
$schema->objects['project'] = array();
$schema->objects['project']['id'] = array('type' => 'number', 'name' => $this->lang->project->id);
$schema->objects['project']['name'] = array('type' => 'string', 'name' => $this->lang->project->name);
+41
View File
@@ -0,0 +1,41 @@
<?php
$this->app->loadLang('product');
$this->app->loadLang('program');
$this->app->loadLang('tree');
$schema = new stdclass();
$schema->primaryTable = 'product';
$schema->tables = array();
$schema->tables['product'] = 'zt_product';
$schema->tables['program'] = 'zt_project';
$schema->tables['line'] = 'zt_module';
$schema->joins = array();
$schema->joins['program'] = 'product.program = program.id';
$schema->joins['line'] = 'product.line = line.id';
$schema->fields = array();
$schema->fields['id'] = array('type' => 'number', 'name' => $this->lang->product->id);
$schema->fields['program'] = array('type' => 'object', 'name' => $this->lang->product->program, 'object' => 'program', 'show' => 'program.name');
$schema->fields['line'] = array('type' => 'object', 'name' => $this->lang->product->line, 'object' => 'line', 'show' => 'line.name');
$schema->fields['name'] = array('type' => 'string', 'name' => $this->lang->product->name);
$schema->fields['code'] = array('type' => 'string', 'name' => $this->lang->product->code);
$schema->fields['type'] = array('type' => 'option', 'name' => $this->lang->product->type, 'options' => $this->lang->product->typeList);
$schema->fields['status'] = array('type' => 'option', 'name' => $this->lang->product->status, 'options' => $this->lang->product->statusList);
$schema->fields['desc'] = array('type' => 'string', 'name' => $this->lang->product->desc);
$schema->fields['PO'] = array('type' => 'user', 'name' => $this->lang->product->PO);
$schema->fields['QD'] = array('type' => 'user', 'name' => $this->lang->product->QD);
$schema->fields['RD'] = array('type' => 'user', 'name' => $this->lang->product->RD);
$schema->fields['createdBy'] = array('type' => 'user', 'name' => $this->lang->product->createdBy);
$schema->fields['createdDate'] = array('type' => 'date', 'name' => $this->lang->product->createdDate);
$schema->objects = array();
$schema->objects['program'] = array();
$schema->objects['program']['id'] = array('type' => 'number', 'name' => $this->lang->program->id);
$schema->objects['program']['name'] = array('type' => 'string', 'name' => $this->lang->program->name);
$schema->objects['line'] = array();
$schema->objects['line']['name'] = array('type' => 'string', 'name' => $this->lang->product->line);
+28
View File
@@ -0,0 +1,28 @@
<?php
$this->app->loadLang('productplan');
$this->app->loadLang('product');
$schema = new stdclass();
$schema->primaryTable = 'productplan';
$schema->tables = array();
$schema->tables['productplan'] = 'zt_productplan';
$schema->tables['product'] = 'zt_product';
$schema->joins = array();
$schema->joins['product'] = 'productplan.product = product.id';
$schema->fields = array();
$schema->fields['product'] = array('type' => 'object', 'name' => $this->lang->productplan->product, 'object' => 'product', 'show' => 'product.name');
$schema->fields['title'] = array('type' => 'string', 'name' => $this->lang->productplan->title);
$schema->fields['status'] = array('type' => 'option', 'name' => $this->lang->productplan->status, 'options' => $this->lang->productplan->statusList);
$schema->fields['desc'] = array('type' => 'string', 'name' => $this->lang->productplan->desc);
$schema->fields['begin'] = array('type' => 'date', 'name' => $this->lang->productplan->begin);
$schema->fields['end'] = array('type' => 'date', 'name' => $this->lang->productplan->end);
$schema->objects = array();
$schema->objects['product'] = array();
$schema->objects['product']['id'] = array('type' => 'number', 'name' => $this->lang->product->id);
$schema->objects['product']['name'] = array('type' => 'string', 'name' => $this->lang->product->name);
+30
View File
@@ -0,0 +1,30 @@
<?php
$this->app->loadLang('project');
$this->app->loadLang('product');
$schema = new stdclass();
$schema->primaryTable = 'project';
$schema->tables = array();
$schema->tables['project'] = 'zt_project';
$schema->joins = array();
$schema->fields = array();
$schema->fields['name'] = array('type' => 'string', 'name' => $this->lang->project->name);
$schema->fields['code'] = array('type' => 'string', 'name' => $this->lang->project->code);
$schema->fields['model'] = array('type' => 'option', 'name' => $this->lang->project->model, 'options' => $this->lang->project->modelList);
$schema->fields['type'] = array('type' => 'option', 'name' => $this->lang->project->type, 'options' => $this->lang->project->typeList);
$schema->fields['status'] = array('type' => 'option', 'name' => $this->lang->project->status, 'options' => $this->lang->project->statusList);
$schema->fields['desc'] = array('type' => 'string', 'name' => $this->lang->project->desc);
$schema->fields['begin'] = array('type' => 'date', 'name' => $this->lang->project->begin);
$schema->fields['end'] = array('type' => 'date', 'name' => $this->lang->project->end);
$schema->fields['PO'] = array('type' => 'user', 'name' => $this->lang->product->PO);
$schema->fields['PM'] = array('type' => 'user', 'name' => $this->lang->project->common . $this->lang->project->PM);
$schema->fields['QD'] = array('type' => 'user', 'name' => $this->lang->project->QD);
$schema->fields['RD'] = array('type' => 'user', 'name' => $this->lang->project->RD);
$schema->fields['openedBy'] = array('type' => 'user', 'name' => $this->lang->project->openedBy);
$schema->fields['openedDate'] = array('type' => 'date', 'name' => $this->lang->project->openedDate);
$schema->objects = array();
+46
View File
@@ -0,0 +1,46 @@
<?php
$this->app->loadLang('release');
$this->app->loadLang('product');
$this->app->loadLang('project');
$this->app->loadLang('build');
$schema = new stdclass();
$schema->primaryTable = 'release';
$schema->tables = array();
$schema->tables['release'] = 'zt_release';
$schema->tables['product'] = 'zt_product';
$schema->tables['project'] = 'zt_project';
$schema->tables['build'] = 'zt_build';
$schema->joins = array();
$schema->joins['product'] = 'release.product = product.id';
$schema->joins['project'] = 'release.project = project.id';
$schema->joins['build'] = 'release.build = build.id';
$schema->fields = array();
$schema->fields['product'] = array('type' => 'object', 'name' => $this->lang->release->product, 'object' => 'product', 'show' => 'product.name');
$schema->fields['project'] = array('type' => 'object', 'name' => $this->lang->release->project, 'object' => 'project', 'show' => 'project.name');
$schema->fields['build'] = array('type' => 'object', 'name' => $this->lang->release->build, 'object' => 'build', 'show' => 'build.name');
$schema->fields['name'] = array('type' => 'string', 'name' => $this->lang->release->name);
$schema->fields['status'] = array('type' => 'option', 'name' => $this->lang->release->status, 'options' => $this->lang->release->statusList);
$schema->fields['desc'] = array('type' => 'string', 'name' => $this->lang->release->desc);
$schema->fields['date'] = array('type' => 'date', 'name' => $this->lang->release->date);
$schema->fields['stories'] = array('type' => 'string', 'name' => $this->lang->release->stories);
$schema->fields['bugs'] = array('type' => 'string', 'name' => $this->lang->release->bugs);
$schema->fields['leftBugs'] = array('type' => 'string', 'name' => $this->lang->release->leftBugs);
$schema->objects = array();
$schema->objects['product'] = array();
$schema->objects['product']['id'] = array('type' => 'number', 'name' => $this->lang->product->id);
$schema->objects['product']['name'] = array('type' => 'string', 'name' => $this->lang->product->name);
$schema->objects['project'] = array();
$schema->objects['project']['id'] = array('type' => 'number', 'name' => $this->lang->project->id);
$schema->objects['project']['name'] = array('type' => 'string', 'name' => $this->lang->project->name);
$schema->objects['build'] = array();
$schema->objects['build']['id'] = array('type' => 'number', 'name' => $this->lang->build->id);
$schema->objects['build']['name'] = array('type' => 'string', 'name' => $this->lang->build->common);
+49
View File
@@ -0,0 +1,49 @@
<?php
$this->app->loadLang('product');
$this->app->loadLang('productplan');
$this->app->loadLang('story');
$this->app->loadLang('project');
$this->app->loadLang('tree');
$this->app->loadLang('dataview');
$schema = new stdclass();
$schema->primaryTable = 'story';
$schema->tables = array();
$schema->tables['story'] = 'zt_story';
$schema->tables['product'] = 'zt_product';
$schema->tables['productline'] = 'zt_module';
$schema->tables['productplan'] = 'zt_productplan';
$schema->tables['program'] = 'zt_project';
$schema->tables['project'] = 'zt_project';
$schema->tables['storymodule'] = 'zt_module';
$schema->tables['storyspec'] = 'zt_storyspec';
$schema->joins = array();
$schema->joins['product'] = 'product.id = story.product';
$schema->joins['storymodule'] = 'storymodule.id = story.module';
$schema->joins['storyspec'] = 'storyspec.story = story.id';
$schema->fields = array();
$schema->fields['id'] = array('type' => 'number', 'name' => $this->lang->story->id);
$schema->fields['title'] = array('type' => 'string', 'name' => $this->lang->story->title);
$schema->fields['status'] = array('type' => 'option', 'name' => $this->lang->story->status, 'options' => $this->lang->story->statusList);
$schema->fields['stage'] = array('type' => 'option', 'name' => $this->lang->story->stage, 'options' => $this->lang->story->stageList);
$schema->fields['pri'] = array('type' => 'option', 'name' => $this->lang->story->pri, 'options' => $this->lang->story->priList);
$schema->fields['product'] = array('type' => 'object', 'name' => $this->lang->story->product, 'object' => 'product', 'show' => 'product.name');
$schema->fields['storymodule'] = array('type' => 'object', 'name' => $this->lang->story->module, 'object' => 'storymodule', 'show' => 'storymodule.name');
$schema->fields['closedDate'] = array('type' => 'date', 'name' => $this->lang->story->closedDate);
$schema->fields['closedReason'] = array('type' => 'option', 'name' => $this->lang->story->closedReason, 'options' => $this->lang->story->reasonList);
$schema->fields['openedBy'] = array('type' => 'user', 'name' => $this->lang->story->openedBy);
$schema->fields['openedDate'] = array('type' => 'date', 'name' => $this->lang->story->openedDate);
$schema->objects = array();
$schema->objects['product'] = array();
$schema->objects['product']['id'] = array('type' => 'number', 'name' => $this->lang->product->id);
$schema->objects['product']['name'] = array('type' => 'string', 'name' => $this->lang->product->common);
$schema->objects['storymodule'] = array();
$schema->objects['storymodule']['id'] = array('type' => 'number', 'name' => $this->lang->dataview->id);
$schema->objects['storymodule']['name'] = array('type' => 'string', 'name' => $this->lang->tree->name);
+63
View File
@@ -0,0 +1,63 @@
<?php
$this->app->loadLang('task');
$this->app->loadLang('project');
$this->app->loadLang('execution');
$this->app->loadLang('story');
$this->app->loadLang('tree');
$this->app->loadLang('dataview');
$schema = new stdclass();
$schema->primaryTable = 'task';
$schema->tables = array();
$schema->tables['task'] = 'zt_task';
$schema->tables['project'] = 'zt_project';
$schema->tables['execution'] = 'zt_project';
$schema->tables['story'] = 'zt_story';
$schema->tables['taskmodule'] = 'zt_module';
$schema->joins = array();
$schema->joins['execution'] = 'task.execution = execution.id';
$schema->joins['project'] = 'task.project = project.id';
$schema->joins['story'] = 'task.story = story.id';
$schema->joins['taskmodule'] = 'task.module = taskmodule.id';
$schema->fields = array();
$schema->fields['project'] = array('type' => 'object', 'name' => $this->lang->task->project, 'object' => 'project', 'show' => 'project.name');
$schema->fields['execution'] = array('type' => 'object', 'name' => $this->lang->task->execution, 'object' => 'execution', 'show' => 'execution.name');
$schema->fields['story'] = array('type' => 'object', 'name' => $this->lang->task->story, 'object' => 'story', 'show' => 'story.title');
$schema->fields['taskmodule'] = array('type' => 'object', 'name' => $this->lang->task->module, 'object' => 'taskmodule', 'show' => 'taskmodule.name');
$schema->fields['name'] = array('type' => 'string', 'name' => $this->lang->task->name);
$schema->fields['pri'] = array('type' => 'option', 'name' => $this->lang->task->pri, 'options' => $this->lang->task->priList);
$schema->fields['type'] = array('type' => 'option', 'name' => $this->lang->task->type, 'options' => $this->lang->task->typeList);
$schema->fields['status'] = array('type' => 'option', 'name' => $this->lang->task->status, 'options' => $this->lang->task->statusList);
$schema->fields['desc'] = array('type' => 'string', 'name' => $this->lang->task->desc);
$schema->fields['estimate'] = array('type' => 'string', 'name' => $this->lang->task->estimate);
$schema->fields['consumed'] = array('type' => 'string', 'name' => $this->lang->task->consumed);
$schema->fields['left'] = array('type' => 'string', 'name' => $this->lang->task->left);
$schema->fields['estStarted'] = array('type' => 'date', 'name' => $this->lang->task->estStarted);
$schema->fields['deadline'] = array('type' => 'date', 'name' => $this->lang->task->deadline);
$schema->fields['assignedTo'] = array('type' => 'user', 'name' => $this->lang->task->assignedTo);
$schema->fields['finishedBy'] = array('type' => 'user', 'name' => $this->lang->task->finishedBy);
$schema->fields['closedBy'] = array('type' => 'user', 'name' => $this->lang->task->closedBy);
$schema->fields['openedBy'] = array('type' => 'user', 'name' => $this->lang->task->openedBy);
$schema->fields['openedDate'] = array('type' => 'date', 'name' => $this->lang->task->openedDate);
$schema->objects = array();
$schema->objects['project'] = array();
$schema->objects['project']['id'] = array('type' => 'number', 'name' => $this->lang->project->id);
$schema->objects['project']['name'] = array('type' => 'string', 'name' => $this->lang->project->name);
$schema->objects['execution'] = array();
$schema->objects['execution']['id'] = array('type' => 'number', 'name' => $this->lang->execution->id);
$schema->objects['execution']['name'] = array('type' => 'string', 'name' => $this->lang->execution->name);
$schema->objects['story'] = array();
$schema->objects['story']['id'] = array('type' => 'number', 'name' => $this->lang->story->id);
$schema->objects['story']['title'] = array('type' => 'string', 'name' => $this->lang->story->title);
$schema->objects['taskmodule'] = array();
$schema->objects['taskmodule']['id'] = array('type' => 'number', 'name' => $this->lang->dataview->id);
$schema->objects['taskmodule']['name'] = array('type' => 'string', 'name' => $this->lang->tree->name);
+36
View File
@@ -0,0 +1,36 @@
<?php
$this->app->loadLang('task');
$this->app->loadLang('project');
$this->app->loadLang('execution');
$teamLang = new stdclass();
$teamLang->type = '对象类型';
$teamLang->typeList['task'] = '任务';
$teamLang->typeList['execution'] = '执行';
$teamLang->typeList['project'] = '项目';
$schema = new stdclass();
$schema->primaryTable = 'team';
$schema->tables = array();
$schema->tables['team'] = 'zt_team';
$schema->tables['project'] = 'zt_project';
$schema->tables['execution'] = 'zt_project';
$schema->tables['task'] = 'zt_task';
$schema->joins = array();
$schema->joins['execution'] = 'team.root = execution.id';
$schema->joins['project'] = 'team.root = project.id';
$schema->joins['task'] = 'team.root = task.id';
$schema->fields = array();
$schema->fields['root'] = array('type' => 'object', 'name' => $this->lang->execution->common, 'object' => 'execution', 'show' => 'execution.name');
$schema->fields['account'] = array('type' => 'user', 'name' => $this->lang->team->account);
$schema->fields['type'] = array('type' => 'option', 'name' => $teamLang->type, 'options' => $teamLang->typeList);
$schema->objects = array();
$schema->objects['execution'] = array();
$schema->objects['execution']['id'] = array('type' => 'number', 'name' => $this->lang->execution->id);
$schema->objects['execution']['name'] = array('type' => 'string', 'name' => $this->lang->execution->name);
+52
View File
@@ -0,0 +1,52 @@
<?php
$this->app->loadLang('product');
$this->app->loadLang('testcase');
$this->app->loadLang('testtask');
$this->app->loadLang('tree');
$this->app->loadLang('story');
$this->app->loadLang('dataview');
$schema = new stdclass();
$schema->primaryTable = 'testcase';
$schema->tables = array();
$schema->tables['testcase'] = 'zt_case';
$schema->tables['product'] = 'zt_product';
$schema->tables['casemodule'] = 'zt_module';
$schema->tables['story'] = 'zt_story';
$schema->tables['casestep'] = 'zt_casestep';
$schema->joins = array();
$schema->joins['product'] = 'product.id = testcase.product';
$schema->joins['casemodule'] = 'casemodule.id = testcase.module';
$schema->joins['story'] = 'story.id = testcase.story';
$schema->joins['casestep'] = 'casestep.case = testcase.id';
$schema->fields = array();
$schema->fields['id'] = array('type' => 'number', 'name' => $this->lang->testcase->id);
$schema->fields['title'] = array('type' => 'string', 'name' => $this->lang->testcase->title);
$schema->fields['pri'] = array('type' => 'option', 'name' => $this->lang->testcase->pri, 'options' => $this->lang->testcase->priList);
$schema->fields['type'] = array('type' => 'option', 'name' => $this->lang->testcase->type, 'options' => $this->lang->testcase->typeList);
$schema->fields['stage'] = array('type' => 'option', 'name' => $this->lang->testcase->stage, 'options' => $this->lang->testcase->stageList);
$schema->fields['status'] = array('type' => 'option', 'name' => $this->lang->testcase->status, 'options' => $this->lang->testcase->statusList);
$schema->fields['version'] = array('type' => 'number', 'name' => $this->lang->testcase->version);
$schema->fields['product'] = array('type' => 'object', 'name' => $this->lang->testcase->product, 'object' => 'product', 'show' => 'product.name');
$schema->fields['story'] = array('type' => 'object', 'name' => $this->lang->testcase->story, 'object' => 'story', 'show' => 'story.title');
$schema->fields['casemodule'] = array('type' => 'object', 'name' => $this->lang->testcase->module, 'object' => 'casemodule', 'show' => 'casemodule.name');
$schema->fields['openedBy'] = array('type' => 'user', 'name' => $this->lang->testcase->openedBy);
$schema->fields['openedDate'] = array('type' => 'date', 'name' => $this->lang->testcase->openedDate);
$schema->objects = array();
$schema->objects['product'] = array();
$schema->objects['product']['id'] = array('type' => 'number', 'name' => $this->lang->product->id);
$schema->objects['product']['name'] = array('type' => 'string', 'name' => $this->lang->product->common);
$schema->objects['casemodule'] = array();
$schema->objects['casemodule']['id'] = array('type' => 'number', 'name' => $this->lang->dataview->id);
$schema->objects['casemodule']['name'] = array('type' => 'string', 'name' => $this->lang->tree->name);
$schema->objects['story'] = array();
$schema->objects['story']['id'] = array('type' => 'number', 'name' => $this->lang->story->id);
$schema->objects['story']['title'] = array('type' => 'string', 'name' => $this->lang->story->title);
+84
View File
@@ -0,0 +1,84 @@
<?php
$this->app->loadLang('testcase');
$this->app->loadLang('testtask');
$this->app->loadLang('project');
$this->app->loadLang('execution');
$this->app->loadLang('tree');
$this->app->loadLang('build');
$this->app->loadLang('caselib');
$this->app->loadLang('product');
$this->app->loadLang('dataview');
$schema = new stdclass();
$schema->primaryTable = 'testresult';
$schema->tables = array();
$schema->tables['testcase'] = 'zt_case';
$schema->tables['testrun'] = 'zt_testrun';
$schema->tables['testresult'] = 'zt_testresult';
$schema->tables['testtask'] = 'zt_testtask';
$schema->tables['project'] = 'zt_project';
$schema->tables['execution'] = 'zt_project';
$schema->tables['casemodule'] = 'zt_module';
$schema->tables['build'] = 'zt_build';
$schema->tables['caselib'] = 'zt_testsuite';
$schema->tables['product'] = 'zt_product';
$schema->joins = array();
$schema->joins['testcase'] = 'testcase.id = testresult.case';
$schema->joins['testrun'] = 'testrun.id = testresult.run';
$schema->joins['testtask'] = 'testrun.task = testtask.id';
$schema->joins['project'] = 'project.id = testtask.project';
$schema->joins['execution'] = 'execution.id = testtask.execution';
$schema->joins['casemodule'] = 'casemodule.id = testcase.module';
$schema->joins['build'] = 'build.id = testtask.build';
$schema->joins['caselib'] = 'caselib.id = testcase.lib';
$schema->joins['product'] = 'product.id = testcase.product';
$schema->fields = array();
$schema->fields['caseResult'] = array('type' => 'option', 'name' => $this->lang->testtask->caseResult, 'options' => $this->lang->testcase->resultList);
$schema->fields['stepResults'] = array('type' => 'json', 'name' => $this->lang->testtask->stepResults);
$schema->fields['lastRunner'] = array('type' => 'user', 'name' => $this->lang->testtask->lastRunner);
$schema->fields['date'] = array('type' => 'date', 'name' => $this->lang->testtask->date);
$schema->fields['testcase'] = array('type' => 'object', 'name' => $this->lang->testcase->common, 'object' => 'testcase', 'show' => 'testcase.title');
$schema->fields['testtask'] = array('type' => 'object', 'name' => $this->lang->testtask->common, 'object' => 'testtask', 'show' => 'testtask.name');
$schema->fields['execution'] = array('type' => 'object', 'name' => $this->lang->execution->common, 'object' => 'execution', 'show' => 'execution.name');
$schema->fields['project'] = array('type' => 'object', 'name' => $this->lang->project->common, 'object' => 'project', 'show' => 'execution.name');
$schema->fields['casemodule'] = array('type' => 'object', 'name' => $this->lang->tree->common, 'object' => 'casemodule', 'show' => 'casemodule.name');
$schema->fields['build'] = array('type' => 'object', 'name' => $this->lang->build->common, 'object' => 'build', 'show' => 'build.name');
$schema->fields['caselib'] = array('type' => 'object', 'name' => $this->lang->caselib->common, 'object' => 'caselib', 'show' => 'caselib.name');
$schema->objects = array();
$schema->objects['testcase'] = array();
$schema->objects['testcase']['id'] = array('type' => 'number', 'name' => $this->lang->testcase->id);
$schema->objects['testcase']['title'] = array('type' => 'string', 'name' => $this->lang->testcase->title);
$schema->objects['testtask'] = array();
$schema->objects['testtask']['id'] = array('type' => 'number', 'name' => $this->lang->testtask->id);
$schema->objects['testtask']['name'] = array('type' => 'string', 'name' => $this->lang->testtask->name);
$schema->objects['build'] = array();
$schema->objects['build']['id'] = array('type' => 'number', 'name' => $this->lang->dataview->id);
$schema->objects['build']['name'] = array('type' => 'string', 'name' => $this->lang->build->name);
$schema->objects['project'] = array();
$schema->objects['project']['id'] = array('type' => 'number', 'name' => $this->lang->project->id);
$schema->objects['project']['name'] = array('type' => 'string', 'name' => $this->lang->project->name);
$schema->objects['execution'] = array();
$schema->objects['execution']['id'] = array('type' => 'number', 'name' => $this->lang->execution->id);
$schema->objects['execution']['name'] = array('type' => 'string', 'name' => $this->lang->execution->name);
$schema->objects['casemodule'] = array();
$schema->objects['casemodule']['id'] = array('type' => 'number', 'name' => $this->lang->dataview->id);
$schema->objects['casemodule']['name'] = array('type' => 'string', 'name' => $this->lang->dataview->name);
$schema->objects['caselib'] = array();
$schema->objects['caselib']['id'] = array('type' => 'number', 'name' => $this->lang->dataview->id);
$schema->objects['caselib']['name'] = array('type' => 'string', 'name' => $this->lang->caselib->name);
$schema->objects['product'] = array();
$schema->objects['product']['id'] = array('type' => 'number', 'name' => $this->lang->product->id);
$schema->objects['product']['name'] = array('type' => 'string', 'name' => $this->lang->product->name);
+78
View File
@@ -0,0 +1,78 @@
<?php
$this->app->loadLang('testcase');
$this->app->loadLang('testtask');
$this->app->loadLang('tree');
$this->app->loadLang('project');
$this->app->loadLang('execution');
$this->app->loadLang('build');
$this->app->loadLang('product');
$this->app->loadLang('dataview');
$schema = new stdclass();
$schema->primaryTable = 'testrun';
$schema->tables = array();
$schema->tables['testrun'] = 'zt_testrun';
$schema->tables['testcase'] = 'zt_case';
$schema->tables['testtask'] = 'zt_testtask';
$schema->tables['casemodule'] = 'zt_module';
$schema->tables['project'] = 'zt_project';
$schema->tables['execution'] = 'zt_project';
$schema->tables['build'] = 'zt_build';
$schema->tables['product'] = 'zt_product';
$schema->joins = array();
$schema->joins['testcase'] = 'testcase.id = testrun.case';
$schema->joins['product'] = 'product.id = testcase.product';
$schema->joins['testtask'] = 'testtask.id = testrun.task';
$schema->joins['casemodule'] = 'casemodule.id = testcase.module';
$schema->joins['project'] = 'project.id = testtask.project';
$schema->joins['execution'] = 'execution.id = testtask.execution';
$schema->joins['build'] = 'build.id = testtask.build';
$schema->fields = array();
$schema->fields['testtask'] = array('type' => 'object', 'name' => $this->lang->testtask->common, 'object' => 'testtask', 'show' => 'testtask.name');
$schema->fields['testcase'] = array('type' => 'object', 'name' => $this->lang->testcase->common, 'object' => 'testcase', 'show' => 'testcase.title');
$schema->fields['assignedTo'] = array('type' => 'user', 'name' => $this->lang->testcase->assignedTo);
$schema->fields['project'] = array('type' => 'object', 'name' => $this->lang->project->common, 'object' => 'project', 'show' => 'execution.name');
$schema->fields['build'] = array('type' => 'object', 'name' => $this->lang->build->common, 'object' => 'build', 'show' => 'build.name');
$schema->fields['execution'] = array('type' => 'object', 'name' => $this->lang->execution->common, 'object' => 'execution', 'show' => 'execution.name');
$schema->fields['casemodule'] = array('type' => 'object', 'name' => $this->lang->tree->common, 'object' => 'casemodule', 'show' => 'casemodule.name');
$schema->fields['lastRunner'] = array('type' => 'user', 'name' => $this->lang->testtask->lastRunner);
$schema->fields['lastRunDate'] = array('type' => 'user', 'name' => $this->lang->testtask->lastRunDate);
$schema->fields['lastRunResult'] = array('type' => 'option', 'name' => $this->lang->testtask->lastRunResult, 'options' => $this->lang->testcase->resultList);
$schema->objects = array();
$schema->objects['testcase'] = array();
$schema->objects['testcase']['id'] = array('type' => 'number', 'name' => $this->lang->testcase->id);
$schema->objects['testcase']['title'] = array('type' => 'string', 'name' => $this->lang->testcase->title);
$schema->objects['testtask'] = array();
$schema->objects['testtask']['id'] = array('type' => 'number', 'name' => $this->lang->testtask->id);
$schema->objects['testtask']['name'] = array('type' => 'string', 'name' => $this->lang->testtask->name);
$schema->objects['testcase'] = array();
$schema->objects['testcase']['id'] = array('type' => 'number', 'name' => $this->lang->testcase->id);
$schema->objects['testcase']['title'] = array('type' => 'string', 'name' => $this->lang->testcase->title);
$schema->objects['build'] = array();
$schema->objects['build']['id'] = array('type' => 'number', 'name' => $this->lang->dataview->id);
$schema->objects['build']['name'] = array('type' => 'string', 'name' => $this->lang->build->name);
$schema->objects['project'] = array();
$schema->objects['project']['id'] = array('type' => 'number', 'name' => $this->lang->project->id);
$schema->objects['project']['name'] = array('type' => 'string', 'name' => $this->lang->project->name);
$schema->objects['execution'] = array();
$schema->objects['execution']['id'] = array('type' => 'number', 'name' => $this->lang->execution->id);
$schema->objects['execution']['name'] = array('type' => 'string', 'name' => $this->lang->execution->name);
$schema->objects['casemodule'] = array();
$schema->objects['casemodule']['id'] = array('type' => 'number', 'name' => $this->lang->dataview->id);
$schema->objects['casemodule']['name'] = array('type' => 'string', 'name' => $this->lang->dataview->name);
$schema->objects['product'] = array();
$schema->objects['product']['id'] = array('type' => 'number', 'name' => $this->lang->product->id);
$schema->objects['product']['name'] = array('type' => 'string', 'name' => $this->lang->product->name);
+56
View File
@@ -0,0 +1,56 @@
<?php
$this->app->loadLang('product');
$this->app->loadLang('project');
$this->app->loadLang('execution');
$this->app->loadLang('build');
$this->app->loadLang('testtask');
$schema = new stdclass();
$schema->primaryTable = 'testtask';
$schema->tables = array();
$schema->tables['product'] = 'zt_product';
$schema->tables['project'] = 'zt_project';
$schema->tables['execution'] = 'zt_project';
$schema->tables['build'] = 'zt_build';
$schema->tables['testtask'] = 'zt_testtask';
$schema->joins = array();
$schema->joins['product'] = 'product.id = testtask.product';
$schema->joins['project'] = 'project.id = testtask.project';
$schema->joins['execution'] = 'execution.id = testtask.execution';
$schema->joins['build'] = 'build.id = testtask.build';
$schema->fields = array();
$schema->fields['product'] = array('type' => 'object', 'name' => $this->lang->testtask->product, 'object' => 'product', 'show' => 'product.name');
$schema->fields['project'] = array('type' => 'object', 'name' => $this->lang->testtask->project, 'object' => 'project', 'show' => 'project.name');
$schema->fields['execution'] = array('type' => 'object', 'name' => $this->lang->testtask->execution, 'object' => 'execution', 'show' => 'execution.name');
$schema->fields['build'] = array('type' => 'object', 'name' => $this->lang->testtask->build, 'object' => 'build', 'show' => 'build.name');
$schema->fields['id'] = array('type' => 'number', 'name' => $this->lang->testtask->id);
$schema->fields['name'] = array('type' => 'string', 'name' => $this->lang->testtask->name);
$schema->fields['type'] = array('type' => 'option', 'name' => $this->lang->testtask->type, 'options' => $this->lang->testtask->typeList);
$schema->fields['owner'] = array('type' => 'user', 'name' => $this->lang->testtask->owner);
$schema->fields['pri'] = array('type' => 'option', 'name' => $this->lang->testtask->pri, 'options' => $this->lang->testtask->priList);
$schema->fields['begin'] = array('type' => 'date', 'name' => $this->lang->testtask->begin);
$schema->fields['end'] = array('type' => 'date', 'name' => $this->lang->testtask->end);
$schema->fields['status'] = array('type' => 'option', 'name' => $this->lang->testtask->status, 'options' => $this->lang->testtask->statusList);
$schema->objects = array();
$schema->objects['product'] = array();
$schema->objects['product']['id'] = array('type' => 'number', 'name' => $this->lang->product->id);
$schema->objects['product']['name'] = array('type' => 'string', 'name' => $this->lang->product->name);
$schema->objects['project'] = array();
$schema->objects['project']['id'] = array('type' => 'number', 'name' => $this->lang->project->id);
$schema->objects['project']['name'] = array('type' => 'string', 'name' => $this->lang->project->name);
$schema->objects['execution'] = array();
$schema->objects['execution']['id'] = array('type' => 'number', 'name' => $this->lang->execution->id);
$schema->objects['execution']['name'] = array('type' => 'string', 'name' => $this->lang->execution->name);
$schema->objects['build'] = array();
$schema->objects['build']['id'] = array('type' => 'number', 'name' => $this->lang->build->id);
$schema->objects['build']['name'] = array('type' => 'string', 'name' => $this->lang->build->name);
+1 -1
View File
@@ -163,10 +163,10 @@ class doc extends control
}
}
if($type == 'execution') $objects = $this->execution->getPairs(0, 'all', 'multiple,leaf,noprefix');
if($type == 'execution')
{
$objects = $this->execution->getPairs(0, 'sprint,stage', 'multiple,leaf,noprefix');
$execution = $this->execution->getByID($objectID);
if($execution->type == 'stage') $this->lang->doc->execution = str_replace($this->lang->executionCommon, $this->lang->project->stage, $this->lang->doc->execution);
}
+39
View File
@@ -2391,4 +2391,43 @@ class treeModel extends model
return $this->getByID($moduleID);
}
/**
* Get group pairs.
*
* @param int $dimensionID
* @param int $parentGroup
* @param int $grade
* @param string $type
* @access public
* @return array
*/
public function getGroupPairs($dimensionID = 0, $parentGroup = 0, $grade = 2, $type = 'chart')
{
$groups = $this->dao->select('id,name,grade,parent')->from(TABLE_MODULE)
->where('root')->eq($dimensionID)
->beginIF(!empty($parentGroup))->andWhere('root')->eq($dimensionID)->fi()
->andWhere('type')->eq($type)
->andWhere('deleted')->eq(0)
->orderBy('order')
->fetchGroup('grade', 'id');
$groupPairs = array();
if(!empty($groups[1]))
{
foreach($groups[1] as $parentGroup)
{
if($grade == 1) $groupPairs[$parentGroup->id] = $parentGroup->name;
if($grade == 2 and !empty($groups[2]))
{
foreach($groups[2] as $childGroup)
{
if($parentGroup->id == $childGroup->parent) $groupPairs[$childGroup->id] = '/' . $parentGroup->name . '/' . $childGroup->name;
}
}
}
}
return $groupPairs;
}
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More