* finish task #2938.
This commit is contained in:
@@ -284,6 +284,7 @@ $lang->bug->report->bugsPerResolution = new stdclass();
|
||||
$lang->bug->report->bugsPerStatus = new stdclass();
|
||||
$lang->bug->report->bugsPerActivatedCount = new stdclass();
|
||||
$lang->bug->report->bugsPerType = new stdclass();
|
||||
$lang->bug->report->bugsPerPri = new stdclass();
|
||||
$lang->bug->report->bugsPerAssignedTo = new stdclass();
|
||||
$lang->bug->report->bugLiveDays = new stdclass();
|
||||
$lang->bug->report->bugHistories = new stdclass();
|
||||
@@ -302,6 +303,7 @@ $lang->bug->report->bugsPerResolution->graph = new stdclass();
|
||||
$lang->bug->report->bugsPerStatus->graph = new stdclass();
|
||||
$lang->bug->report->bugsPerActivatedCount->graph = new stdclass();
|
||||
$lang->bug->report->bugsPerType->graph = new stdclass();
|
||||
$lang->bug->report->bugsPerPri->graph = new stdclass();
|
||||
$lang->bug->report->bugsPerAssignedTo->graph = new stdclass();
|
||||
$lang->bug->report->bugLiveDays->graph = new stdclass();
|
||||
$lang->bug->report->bugHistories->graph = new stdclass();
|
||||
@@ -327,6 +329,7 @@ $lang->bug->report->bugsPerSeverity->graph->xAxisName = '严重程度';
|
||||
$lang->bug->report->bugsPerResolution->graph->xAxisName = '解决方案';
|
||||
$lang->bug->report->bugsPerStatus->graph->xAxisName = '状态';
|
||||
$lang->bug->report->bugsPerActivatedCount->graph->xAxisName = '激活次数';
|
||||
$lang->bug->report->bugsPerPri->graph->xAxisName = '优先级';
|
||||
$lang->bug->report->bugsPerType->graph->xAxisName = '类型';
|
||||
$lang->bug->report->bugsPerAssignedTo->graph->xAxisName = '指派给';
|
||||
$lang->bug->report->bugLiveDays->graph->xAxisName = '处理时间';
|
||||
|
||||
@@ -1632,7 +1632,7 @@ class bugModel extends model
|
||||
{
|
||||
$datas = $this->dao->select('pri AS name, COUNT(*) AS value')->from(TABLE_BUG)->where($this->reportCondition())->groupBy('name')->orderBy('value DESC')->fetchAll('name');
|
||||
if(!$datas) return array();
|
||||
foreach($datas as $status => $data) if(isset($this->lang->bug->statusList[$status])) $data->name = $this->lang->bug->statusList[$status];
|
||||
foreach($datas as $status => $data) $data->name = $this->lang->bug->report->bugsPerPri->graph->xAxisName . ':' . $data->name;
|
||||
return $datas;
|
||||
}
|
||||
|
||||
|
||||
@@ -201,6 +201,7 @@ class product extends control
|
||||
$this->view->storyBugs = $storyBugs;
|
||||
$this->view->storyCases = $storyCases;
|
||||
$this->view->param = $param;
|
||||
$this->view->products = $this->products;
|
||||
$this->display();
|
||||
}
|
||||
|
||||
@@ -573,9 +574,22 @@ class product extends control
|
||||
*/
|
||||
public function ajaxGetMatchedItems($keywords, $module, $method, $extra)
|
||||
{
|
||||
$products = $this->dao->select('*')->from(TABLE_PRODUCT)->where('deleted')->eq(0)->andWhere('name')->like("%$keywords%")->orderBy('`order` desc')->fetchAll();
|
||||
$products = $this->dao->select('*')->from(TABLE_PRODUCT)->where('deleted')->eq(0)->orderBy('`order` desc')->fetchAll();
|
||||
$toPinyin = $this->product->toPinyin($products);
|
||||
|
||||
foreach($toPinyin as $key => $value) {
|
||||
if(!strstr($value ,$keywords) && !strstr($key,$keywords)) {
|
||||
unset($toPinyin[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
foreach($products as $key => $product)
|
||||
{
|
||||
if(!isset($toPinyin[$product->name])) {
|
||||
unset($products[$key]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!$this->product->checkPriv($product)) unset($products[$key]);
|
||||
}
|
||||
|
||||
|
||||
@@ -900,4 +900,52 @@ class productModel extends model
|
||||
->limit(1)
|
||||
->fetch();
|
||||
}
|
||||
|
||||
public function toPinyin($products)
|
||||
{
|
||||
global $app;
|
||||
static $pinyin;
|
||||
static $dataKeys;
|
||||
if(empty($pinyin)) $pinyin = $app->loadClass('pinyin');
|
||||
|
||||
$joinOptions = '';
|
||||
$sign = ' aNd ';
|
||||
foreach($products as $value)
|
||||
{
|
||||
if(!isset($dataKeys[$value->name])) $joinOptions .= str_replace($sign, ' and ', $value->name) . $sign;
|
||||
}
|
||||
|
||||
if($joinOptions)
|
||||
{
|
||||
$valuesPinyin = $pinyin->romanize($joinOptions);
|
||||
$signLenth = strlen($sign);
|
||||
$pinyinSign = trim($sign);
|
||||
$pySignLenth = strlen($pinyinSign);
|
||||
while($joinOptions)
|
||||
{
|
||||
$valuePinyin = '';
|
||||
$value = '';
|
||||
|
||||
$pinyinPos = strpos($valuesPinyin, $pinyinSign);
|
||||
if($pinyinPos !== false)
|
||||
{
|
||||
$valuePinyin = substr($valuesPinyin, 0, $pinyinPos);
|
||||
$valuesPinyin = substr($valuesPinyin, $pinyinPos + $pySignLenth);
|
||||
}
|
||||
|
||||
$valuePos = strpos($joinOptions, $sign);
|
||||
if($valuePos === false) break;
|
||||
$value = substr($joinOptions, 0, $valuePos);
|
||||
$joinOptions = substr($joinOptions, $valuePos + $signLenth);
|
||||
|
||||
$valuePinyin = preg_split('/[^a-z]+/iu', trim($valuePinyin));
|
||||
$valueAbbr = '';
|
||||
foreach($valuePinyin as $wordPinyin) if($wordPinyin) $valueAbbr .= $wordPinyin[0];
|
||||
|
||||
$dataKeys[$value] = empty($valuePinyin) ? '' : join($valuePinyin) . ' ' . $valueAbbr;
|
||||
}
|
||||
}
|
||||
|
||||
return $dataKeys;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1896,9 +1896,22 @@ class project extends control
|
||||
*/
|
||||
public function ajaxGetMatchedItems($keywords, $module, $method, $extra)
|
||||
{
|
||||
$projects = $this->dao->select('*')->from(TABLE_PROJECT)->where('deleted')->eq(0)->andWhere('name')->like("%$keywords%")->orderBy('order desc')->fetchAll();
|
||||
$projects = $this->dao->select('*')->from(TABLE_PROJECT)->where('deleted')->eq(0)->orderBy('order desc')->fetchAll();
|
||||
$toPinyin = $this->project->toPinyin($projects);
|
||||
|
||||
foreach($toPinyin as $key => $value) {
|
||||
if(!strstr($value ,$keywords) && !strstr($key,$keywords)) {
|
||||
unset($toPinyin[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
foreach($projects as $key => $project)
|
||||
{
|
||||
if(!isset($toPinyin[$project->name])) {
|
||||
unset($projects[$key]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!$this->project->checkPriv($project)) unset($projects[$key]);
|
||||
}
|
||||
|
||||
|
||||
@@ -2389,4 +2389,52 @@ class projectModel extends model
|
||||
if(isset($fullTrees[0]) and empty($fullTrees[0]->children)) array_shift($fullTrees);
|
||||
return array_values($fullTrees);
|
||||
}
|
||||
|
||||
public function toPinyin($products)
|
||||
{
|
||||
global $app;
|
||||
static $pinyin;
|
||||
static $dataKeys;
|
||||
if(empty($pinyin)) $pinyin = $app->loadClass('pinyin');
|
||||
|
||||
$joinOptions = '';
|
||||
$sign = ' aNd ';
|
||||
foreach($products as $value)
|
||||
{
|
||||
if(!isset($dataKeys[$value->name])) $joinOptions .= str_replace($sign, ' and ', $value->name) . $sign;
|
||||
}
|
||||
|
||||
if($joinOptions)
|
||||
{
|
||||
$valuesPinyin = $pinyin->romanize($joinOptions);
|
||||
$signLenth = strlen($sign);
|
||||
$pinyinSign = trim($sign);
|
||||
$pySignLenth = strlen($pinyinSign);
|
||||
while($joinOptions)
|
||||
{
|
||||
$valuePinyin = '';
|
||||
$value = '';
|
||||
|
||||
$pinyinPos = strpos($valuesPinyin, $pinyinSign);
|
||||
if($pinyinPos !== false)
|
||||
{
|
||||
$valuePinyin = substr($valuesPinyin, 0, $pinyinPos);
|
||||
$valuesPinyin = substr($valuesPinyin, $pinyinPos + $pySignLenth);
|
||||
}
|
||||
|
||||
$valuePos = strpos($joinOptions, $sign);
|
||||
if($valuePos === false) break;
|
||||
$value = substr($joinOptions, 0, $valuePos);
|
||||
$joinOptions = substr($joinOptions, $valuePos + $signLenth);
|
||||
|
||||
$valuePinyin = preg_split('/[^a-z]+/iu', trim($valuePinyin));
|
||||
$valueAbbr = '';
|
||||
foreach($valuePinyin as $wordPinyin) if($wordPinyin) $valueAbbr .= $wordPinyin[0];
|
||||
|
||||
$dataKeys[$value] = empty($valuePinyin) ? '' : join($valuePinyin) . ' ' . $valueAbbr;
|
||||
}
|
||||
}
|
||||
|
||||
return $dataKeys;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,6 +186,47 @@ class testcase extends control
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* The report page.
|
||||
*
|
||||
* @param int $productID
|
||||
* @param string $browseType
|
||||
* @param int $branchID
|
||||
* @param int $moduleID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function report($productID, $browseType, $branchID, $moduleID)
|
||||
{
|
||||
$this->loadModel('report');
|
||||
$this->view->charts = array();
|
||||
|
||||
if(!empty($_POST))
|
||||
{
|
||||
foreach($this->post->charts as $chart)
|
||||
{
|
||||
$chartFunc = 'getDataOf' . $chart;
|
||||
$chartData = $this->testcase->$chartFunc();
|
||||
$chartOption = $this->lang->testcase->report->$chart;
|
||||
$this->testcase->mergeChartOption($chart);
|
||||
|
||||
$this->view->charts[$chart] = $chartOption;
|
||||
$this->view->datas[$chart] = $this->report->computePercent($chartData);
|
||||
}
|
||||
}
|
||||
|
||||
$this->testcase->setMenu($this->products, $productID, $branchID);
|
||||
$this->view->title = $this->products[$productID] . $this->lang->colon . $this->lang->testcase->common . $this->lang->colon . $this->lang->testcase->reportChart;
|
||||
$this->view->position[] = html::a($this->createLink('testcase', 'browse', "productID=$productID"), $this->products[$productID]);
|
||||
$this->view->position[] = $this->lang->testcase->reportChart;
|
||||
$this->view->productID = $productID;
|
||||
$this->view->browseType = $browseType;
|
||||
$this->view->moduleID = $moduleID;
|
||||
$this->view->checkedCharts = $this->post->charts ? join(',', $this->post->charts) : '';
|
||||
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a test case.
|
||||
*
|
||||
|
||||
@@ -76,6 +76,7 @@ $lang->testcase->import = "导入";
|
||||
$lang->testcase->showImport = "显示导入内容";
|
||||
$lang->testcase->exportTemplet = "导出模板";
|
||||
$lang->testcase->export = "导出数据";
|
||||
$lang->testcase->reportChart = '报表统计';
|
||||
$lang->testcase->confirmChange = '确认用例变动';
|
||||
$lang->testcase->confirmStoryChange = '确认需求变动';
|
||||
$lang->testcase->copy = '复制用例';
|
||||
@@ -161,3 +162,28 @@ $lang->testcase->featureBar['browse']['group'] = '分组查看';
|
||||
$lang->testcase->featureBar['browse']['zerocase'] = '零用例需求';
|
||||
$lang->testcase->featureBar['browse']['suite'] = '套件';
|
||||
$lang->testcase->featureBar['groupcase'] = $lang->testcase->featureBar['browse'];
|
||||
|
||||
/* 统计报表。*/
|
||||
$lang->testcase->report = new stdclass();
|
||||
$lang->testcase->report->common = '报表';
|
||||
$lang->testcase->report->select = '请选择报表类型';
|
||||
$lang->testcase->report->create = '生成报表';
|
||||
|
||||
$lang->testcase->report->charts['testCasePerRunResult'] = '测试用例结果统计';
|
||||
$lang->testcase->report->charts['testCasePerStatus'] = '测试用例状态统计';
|
||||
$lang->testcase->report->charts['testCasePerType'] = '测试用例类型统计';
|
||||
|
||||
$lang->testcase->report->options = new stdclass();
|
||||
$lang->testcase->report->options->graph = new stdclass();
|
||||
$lang->testcase->report->options->type = 'pie';
|
||||
$lang->testcase->report->options->width = 500;
|
||||
$lang->testcase->report->options->height = 140;
|
||||
|
||||
$lang->testcase->report->testCasePerRunResult = new stdclass();
|
||||
$lang->testcase->report->testCasePerStatus = new stdclass();
|
||||
$lang->testcase->report->testCasePerType = new stdclass();
|
||||
|
||||
$lang->testcase->report->testCasePerRunResult->graph = new stdclass();
|
||||
$lang->testcase->report->testCasePerStatus->graph = new stdclass();
|
||||
$lang->testcase->report->testCasePerType->graph = new stdclass();
|
||||
|
||||
|
||||
@@ -1164,4 +1164,83 @@ class testcaseModel extends model
|
||||
|
||||
return $cases;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get report data of testcase per run result.
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getDataOfTestCasePerRunResult()
|
||||
{
|
||||
$datas = $this->dao->select('lastRunResult AS name, COUNT(*) AS value')->from(TABLE_CASE)->where($this->reportCondition())->groupBy('name')->orderBy('value DESC')->fetchAll('name');
|
||||
if(!$datas) return array();
|
||||
foreach($datas as $result => $data) if(isset($this->lang->testcase->resultList[$result])) $data->name = $this->lang->testcase->resultList[$result];
|
||||
return $datas;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get report data of testcase per status.
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getDataOfTestCasePerStatus()
|
||||
{
|
||||
$datas = $this->dao->select('status AS name, COUNT(*) AS value')->from(TABLE_CASE)->where($this->reportCondition())->groupBy('name')->orderBy('value DESC')->fetchAll('name');
|
||||
if(!$datas) return array();
|
||||
foreach($datas as $result => $data) if(isset($this->lang->testcase->statusList[$result])) $data->name = $this->lang->testcase->statusList[$result];
|
||||
return $datas;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get report data of testcase per Type.
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getDataOfTestCasePerType()
|
||||
{
|
||||
$datas = $this->dao->select('type AS name, COUNT(*) AS value')->from(TABLE_CASE)->where($this->reportCondition())->groupBy('name')->orderBy('value DESC')->fetchAll('name');
|
||||
if(!$datas) return array();
|
||||
foreach($datas as $result => $data) if(isset($this->lang->testcase->typeList[$result])) $data->name = $this->lang->testcase->typeList[$result];
|
||||
return $datas;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get report condition from session.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function reportCondition()
|
||||
{
|
||||
if(isset($_SESSION['testcaseQueryCondition']))
|
||||
{
|
||||
if(!$this->session->testcaseOnlyCondition) return 'id in (' . preg_replace('/SELECT .* FROM/', 'SELECT t1.id FROM', $this->session->testcaseQueryCondition) . ')';
|
||||
return $this->session->testcaseQueryCondition;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge the default chart settings and the settings of current chart.
|
||||
*
|
||||
* @param string $chartType
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function mergeChartOption($chartType)
|
||||
{
|
||||
$chartOption = $this->lang->testcase->report->$chartType;
|
||||
$commonOption = $this->lang->testcase->report->options;
|
||||
|
||||
$chartOption->graph->caption = $this->lang->testcase->report->charts[$chartType];
|
||||
if(!isset($chartOption->type)) $chartOption->type = $commonOption->type;
|
||||
if(!isset($chartOption->width)) $chartOption->width = $commonOption->width;
|
||||
if(!isset($chartOption->height)) $chartOption->height = $commonOption->height;
|
||||
|
||||
/* 合并配置。*/
|
||||
foreach($commonOption->graph as $key => $value) if(!isset($chartOption->graph->$key)) $chartOption->graph->$key = $value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,6 +94,7 @@
|
||||
</ul>
|
||||
</div>
|
||||
<?php common::printIcon('testcase', 'import', "productID=$productID&branch=$branch", '', 'button', '', '', 'export cboxElement iframe');?>
|
||||
<?php common::printIcon('testcase', 'report', "productID=$productID&browseType=$browseType&branchID=$branch&moduleID=$moduleID"); ?>
|
||||
</div>
|
||||
<div class='btn-group'>
|
||||
<div class='btn-group' id='createActionMenu'>
|
||||
|
||||
Reference in New Issue
Block a user