需求背景
- 测试人员反馈 禅道通过csv导入的用例数量大的情况下一一去关联需求很麻烦,效率不高

-
修改思路

-
涉及修改 - 自顶向下
view
- testcase/view/browse.html.php
- control
- 添加 batchCaseStoryChange 方法
model
添加 btachCaseStoryChange 调用的model层方法
具体实现
browse.html.php
```php
// FIXME 批量修改 pri 优先级if(common::hasPriv('testcase', 'batchCasePriChange')){echo "<li class='dropdown-submenu'>";echo html::a('javascript:;', $lang->testcase->pri, '', "id='priChangeItem'");echo "<ul class='dropdown-menu'>";unset($lang->testcase->priList['']);foreach($lang->testcase->priList as $key => $result){$actionLink = $this->createLink('testcase', 'batchCasePriChange', "result=$key");echo '<li>' . html::a('#', $result, '', "onclick=\"setFormAction('$actionLink', 'hiddenwin')\"") . '</li>';}echo '</ul></li>';}// end of FIXME
// FIXME 批量修改 story 关联需求if(common::hasPriv('testcase', 'batchCaseStoryChange')){echo "<li class='dropdown-submenu'>";echo html::a('javascript:;', $lang->testcase->story, '', "id='storyChangeItem'");echo "<ul class='dropdown-menu'>";
// unset($lang->testcase->priList[‘’]); foreach($storyList as $key => $result) { $actionLink = $this->createLink(‘testcase’, ‘batchCaseStoryChange’, “result=$key”); echo ‘
if(common::hasPriv('testcase', 'batchCaseTypeChange')){echo "<li class='dropdown-submenu'>";echo html::a('javascript:;', $lang->testcase->type, '', "id='typeChangeItem'");echo "<ul class='dropdown-menu'>";unset($lang->testcase->typeList['']);foreach($lang->testcase->typeList as $key => $result){$actionLink = $this->createLink('testcase', 'batchCaseTypeChange', "result=$key");echo '<li>' . html::a('#', $result, '', "onclick=\"setFormAction('$actionLink', 'hiddenwin')\"") . '</li>';}echo '</ul></li>';}
- 参照原有逻辑,如批量修改用例类来进行本次拓展<a name="bZZhy"></a>## control层拓展```php<?phpinclude '../../control.php';class myTestCase extends testcase{// FIXME 新增 批量更改关联需求/** $result 前端页面传回的目标值****/public function batchCaseStoryChange($result){$caseIdList = $this->post->caseIDList ? $this->post->caseIDList : die(js::locate($this->session->caseList, 'parent'));$caseIDList = array_unique($caseIDList);// 调用新增的 btachCase$this->testcase->batchCaseStoryChange($caseIdList, $result);if(dao::isError()) die(js::error(dao::getError()));die(js::locate($this->session->caseList, 'parent'));}}
public function batchCaseStoryChange($caseIdList, $result){
$now = helper::now();$actions = array();$this->loadModel('action');foreach($caseIdList as $caseID) {$case = new stdClass();$case->lastEditedBy = $this->app->user->account;$case->lastEditedDate = $now;// FIXME 优先级更改为需求变更菜单$case->story = $result;$this->dao->update(TABLE_CASE)->data($case)->autoCheck()->where('id')->eq($caseID)->exec();$this->action->create('case', $caseID, 'Edited', '', ucfirst($result));}
}
- model 层为control 层提供调用方法,- 整体调用链条 control 调用model 方法,获取到数据 渲染至页面。<a name="zeGwm"></a># 坑点- 因是二开功能,所以页面上没有story变量 也就是说,browse页面没有story变量,所以如何吧当前产品的所有需求渲染至页面是本功能二开的一个难点。<a name="PcCiB"></a># 解决思路- 首先去寻找禅道原生代码中类似的逻辑,参考其代码get到当前产品中所有的需求列表,渲染至前端。下见代码```php<?phpinclude '../../control.php';class myTestCase extends testcase{/*** Browse cases.** @param int $productID* @param string $browseType* @param int $param* @param string $orderBy* @param int $recTotal* @param int $recPerPage* @param int $pageID* @access public* @return void*/public function browse($productID = 0, $branch = '', $browseType = 'all', $param = 0, $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1){$this->loadModel('datatable');// FIXME 加载story模块 供后续直接进行调用$this->loadModel('story');/* Set browse type. */$browseType = strtolower($browseType);/* Set browseType, productID, moduleID and queryID. */$productID = $this->product->saveState($productID, $this->products);$branch = ($branch === '') ? (int)$this->cookie->preBranch : (int)$branch;setcookie('preProductID', $productID, $this->config->cookieLife, $this->config->webRoot, '', false, true);setcookie('preBranch', (int)$branch, $this->config->cookieLife, $this->config->webRoot, '', false, true);if($this->cookie->preProductID != $productID or $this->cookie->preBranch != $branch){$_COOKIE['caseModule'] = 0;setcookie('caseModule', 0, 0, $this->config->webRoot, '', false, false);}if($browseType == 'bymodule') setcookie('caseModule', (int)$param, 0, $this->config->webRoot, '', false, false);if($browseType == 'bysuite') setcookie('caseSuite', (int)$param, 0, $this->config->webRoot, '', false, true);if($browseType != 'bymodule') $this->session->set('caseBrowseType', $browseType);$moduleID = ($browseType == 'bymodule') ? (int)$param : ($browseType == 'bysearch' ? 0 : ($this->cookie->caseModule ? $this->cookie->caseModule : 0));$suiteID = ($browseType == 'bysuite') ? (int)$param : ($browseType == 'bymodule' ? ($this->cookie->caseSuite ? $this->cookie->caseSuite : 0) : 0);$queryID = ($browseType == 'bysearch') ? (int)$param : 0;/* Set menu, save session. */$this->testcase->setMenu($this->products, $productID, $branch, $moduleID, $suiteID, $orderBy);$this->session->set('caseList', $this->app->getURI(true));$this->session->set('productID', $productID);$this->session->set('moduleID', $moduleID);$this->session->set('browseType', $browseType);$this->session->set('orderBy', $orderBy);/* Load lang. */$this->app->loadLang('testtask');/* Load pager. */$this->app->loadClass('pager', $static = true);$pager = pager::init($recTotal, $recPerPage, $pageID);$sort = $this->loadModel('common')->appendOrder($orderBy);/* Get test cases. */$cases = $this->testcase->getTestCases($productID, $branch, $browseType, $browseType == 'bysearch' ? $queryID : $suiteID, $moduleID, $sort, $pager);/* save session .*/$this->loadModel('common')->saveQueryCondition($this->dao->get(), 'testcase', $browseType != 'bysearch' ? false : true);/* Process case for check story changed. */$cases = $this->loadModel('story')->checkNeedConfirm($cases);$cases = $this->testcase->appendData($cases);/* Build the search form. */$actionURL = $this->createLink('testcase', 'browse', "productID=$productID&branch=$branch&browseType=bySearch&queryID=myQueryID");$this->config->testcase->search['onMenuBar'] = 'yes';$this->testcase->buildSearchForm($productID, $this->products, $queryID, $actionURL);$showModule = !empty($this->config->datatable->testcaseBrowse->showModule) ? $this->config->datatable->testcaseBrowse->showModule : '';$this->view->modulePairs = $showModule ? $this->tree->getModulePairs($productID, 'case', $showModule) : array();// FIXME assign 赋值需求列表// test -- 调用story 模块下的方法去获取到所有的story列表之后渲染到前端页面// todo 核心代码为$status = '';$limit = 0;$type = 'full';$hasParent = 1;if($moduleID){$moduleID = $this->loadModel('tree')->getStoryModule($moduleID);$moduleID = $this->tree->getAllChildID($moduleID);}$storyStatus = '';if($status == 'noclosed'){$storyStatus = $this->lang->story->statusList;unset($storyStatus['closed']);$storyStatus = array_keys($storyStatus);}// 观察到下面的代码是取得所有需求列表的关键代码,分析其参数构成,进行初始化调用。$stories = $this->story->getProductStoryPairs($productID, $branch ? "0,$branch" : $branch, $moduleID, $storyStatus, 'id_desc', $limit, $type, 'story', $hasParent);// 渲染到前端页面,之后进行测试$this->view->storyList = $stories;/* Assign. */$tree = $moduleID ? $this->tree->getByID($moduleID) : '';$this->view->title = $this->products[$productID] . $this->lang->colon . $this->lang->testcase->common;$this->view->position[] = html::a($this->createLink('testcase', 'browse', "productID=$productID&branch=$branch"), $this->products[$productID]);$this->view->position[] = $this->lang->testcase->common;$this->view->productID = $productID;$this->view->product = $this->product->getById($productID);$this->view->productName = $this->products[$productID];$this->view->modules = $this->tree->getOptionMenu($productID, $viewType = 'case', $startModuleID = 0, $branch);$this->view->moduleTree = $this->tree->getTreeMenu($productID, $viewType = 'case', $startModuleID = 0, array('treeModel', 'createCaseLink'), '', $branch);$this->view->moduleName = $moduleID ? $tree->name : $this->lang->tree->all;$this->view->moduleID = $moduleID;$this->view->summary = $this->testcase->summary($cases);$this->view->pager = $pager;$this->view->users = $this->user->getPairs('noletter');$this->view->orderBy = $orderBy;$this->view->browseType = $browseType;$this->view->param = $param;$this->view->cases = $cases;$this->view->branch = $branch;$this->view->branches = $this->loadModel('branch')->getPairs($productID);$this->view->suiteList = $this->loadModel('testsuite')->getSuites($productID);$this->view->suiteID = $suiteID;$this->view->setModule = true;$this->display();}}
