需求:
现在需要加一个功能,希望可以自由拖动列。受到【模块维护】拖动启发进行改造。
思路:
step1:每一行新增一列,加一个拖动按钮。
step2:前台拖动的时候,鼠标放开时发送请求到后台,执行数据库更新操作。
前提:
1、数据库用例表zt_case启用order列,且每条数据的order值不同。
2、目前查询是用id降序排列,需要修改为order降序。因为数据库已经存在数据,所以需要进行存量数据更新,把已有数据的order更新为随id升序进行升序。
即:
前提修改好之后,我们来修改代码。(以下思路不再写了)
1、\zentaopms\module\testcase\config.php 在最后增加代码:这是【移动】列的信息。其中 common::hasPriv('testcase', 'updateOrder') 后面解释。
$config->testcase->datatable->fieldList['move']['title'] = 'move';
$config->testcase->datatable->fieldList['move']['fixed'] = 'right';
$config->testcase->datatable->fieldList['move']['width'] = '80';
$config->testcase->datatable->fieldList['move']['required'] = 'yes';
$config->testcase->datatable->fieldList['move']['sort'] = 'no';
$config->testcase->datatable->fieldList['move']['canShow'] = common::hasPriv('testcase', 'updateOrder');//此方法的权限,此处用来控制是否展示【移动】列
修改 $config->testcase->datatable->defaultField 值,在最后增加‘move’参数:
$config->testcase->datatable->defaultField = array('id', 'pri', 'title', 'type', 'openedBy', 'lastRunner', 'lastRunDate', 'lastRunResult', 'status', 'bugs', 'results', 'stepNumber', 'actions','move');
2、\zentaopms\module\testcase\lang\zh-cn.php 增加对[move]列的命名:(\zentaopms\module\testcase\lang\下的其他语言文件同样修改)
$lang->testcase->move = '移动';
3、\zentaopms\module\datatable\model.php 的 getSetting($module) 方法修改:
将
$set->show = true;
改为:
$set->show = isset($fieldList[$id]['canShow']) ? $fieldList[$id]['canShow'] : true;
4、上述步骤之后,就会在【操作】列之后生成【移动】列:
然后我们给【移动】列的每一行加上一个小图标:
\zentaopms\module\testcase\model.php printCell 方法:
代码:
$canmoveForOrder = common::hasPriv('testcase', 'updateOrder');//updateOrder方法的权限,此处用来判断是否显示图标
if($id == 'move'){
if($canmoveForOrder){
$class .= ' sortBL icon-move';
}
}
这个步骤做完之后,页面效果:
1、这里代码不用多写了,因为参考其他大佬的代码:【基于原生的JS实现拖动Table行】(但是这段代码里,只看script 之后的就可以。如果你全部拷贝之后展示html页面,一定要往下翻到页面最底部...)
基于原生的JS实现拖动Table行_雾里看花叹朦胧-CSDN博客
2、\zentaopms\module\testcase\view\browse.html.php 参考上面script内容,写入中,然后在 dragEnd: function (e) {}里面,增加post请求:
代码:
$.post('createLink('testcase', 'updateOrder');?>', orders).error(function()
{
bootbox.alert(lang.timeout);
});
上面步骤之后,就可以在前台拖动table列了。
1、\zentaopms\module\testcase\control.php 增加 updateOrder()方法:
/**
* 用order进行排序
*
* @param string $methodName
* @access public
* @return mixed string | bool | array
*/
public function updateOrder(){
if(!empty($_POST)){
$orders = $_POST['orders'];
$this->testcase->updateOrder($orders);
die(js::reload('parent'));
}
}
2、\zentaopms\module\testcase\model.php 增加 updateOrder($orders) 方法:
a.获取这一页所有的order并降序排列,其中select语句用到的id是前台传来的这一页的id数组。
b.前台传来的id,和order进行一一匹配,生成update语句并执行。这样,前台的期望的第一个id是匹配到这一页最大的order,最后一个id匹配到这一页最小的order,符合我们的期望。
这里要写一下思路:
因为涉及到分页,所以一开始想的是每次托动一个数据,就把所有的数据进行order更新,但是一来如果数据量特别大会对数据库造成压力,二来获取前一页的数据又相对麻烦一些。
所以,想到了,先把数据库的数据进行order排序,然后在前台,每次拖动一个数据的时候,只修改本页数据的order。
而前台传来的id就是排序后的,那么我们希望前台传来的第一个id它的order在这一页中最大,第二个id次之...最后一个id对应的order最小。
所以代码实现就是:
1.先倒序查出本页数据的所有order。
2.与前台排序后的id集合进行一一匹配,更新数据库。
/**
* Update testcase' order.
*
* @param array $orders
* @access public
* @return void
*/
public function updateOrder($orders){
asort($orders);//key-value
$orderBy = 'order_desc';
$orderInfo = $this->dao->select('`order`')->from(TABLE_CASE)->where('id')->in(array_keys($orders))->andWhere('deleted')->eq(0)->orderBy($orderBy)->fetchAll();//deleted 数据库字段,0:未删除,1已删除
$orderInfoNew = array();//索引数组
for($i=0;$i 1){
for($i=0;$idao->update(TABLE_CASE)->set('`order`')->eq($orderInt)->where('id')->eq($id)->limit(1)->exec();
}
}
}
至此,其实效果已经实现。
但存量代码查询是id降序查询,我们需要修改为order降序查询。
把\zentaopms\module\testcase\model.php里所有的id_desc改为order_desc。
由于存量数据,我们已经做了修改,并且实现了order变动。但是新增数据时,order还是0,所以需要对新增数据sql进行修改。
新增数据的来源有4个:1、只增加一条;2、批量增加;3、从csv导入;4、从用例库导入。但是由于我们公司的没用从【从用例库导入】这一功能,所以我只修改了前三个的功能。
1、新增私有方法,获取库中的最大order:
/**
* 获取最大的order
*
* @param
* @access private
* @return int
*/
private function getOrderMax(){
$orderInfo = $this->dao->select('`order`')->from(TABLE_CASE)->where('deleted')->eq(0)->groupBy('`order`')->orderBy('order_desc')->fetch();//deleted 数据库字段,0:未删除,1已删除
$orderMax = (int)((array)$orderInfo)['order'];
return $orderMax;
}
2、修改新增数据的sql语句
2-1、只增加一条:
\zentaopms\module\testcase\model.php create($bugID) 方法:
2-2、批量增加:
\zentaopms\module\testcase\model.php batchCreate($productID, $branch, $storyID)方法:
主要代码段:
//获取最大的order
$orderMax = $this->getOrderMax();
$orderCre = $orderMax + 1;
//省略部分代码
foreach($cases->title as $i => $title)
{
if(empty($title)) continue;
$data[$i] = new stdclass();
//省略部分代码
$data[$i]->order = $orderCre;
//省略部分代码
$orderCre = $orderCre+1;
}
2-3、从csv导入
修改 \zentaopms\module\testcase\model.php createFromImport($productID, $branch = 0)方法:
主要代码段:
//获取ordermax
$orderMax = $this->getOrderMax();
$orderCre = $orderMax + 1;
//省略部分代码
foreach($data->product as $key => $product)
{
//省略部分代码
$caseData->order = $orderCre;
//省略部分代码
$orderCre = $orderCre+1;
}
上述五个步骤之后,其实功能已经做好了,但是还有个小问题。就是我在用非admin用户登录之后,会出现没有【移动】列的现象。
这就是我们在第一步骤时说的【其中 common::hasPriv('testcase', 'updateOrder') 后面解释】。
因为禅道项目,module里面的每个模块的control.php的方法对外提供接口时,都对应一个权限,并不是前台页面可以任意调用的。
举个例子:
【zt_user】表有三个用户:
其中ali 和 fff 在对应的group看【zt_usergroup】表:
而group为3 和 group为2的权限各有不同,看【zt_grouppriv】表:(其中 module='testcase'就是我们的【功能测试】模块)
可以看到group=2有调用testcase模块的updateOrder 方法的权限,(即group=2的用户调用common::hasPriv('testcase', 'updateOrder') 返回true);而group=3的用户调用common::hasPriv('testcase', 'updateOrder') 返回false。所以就会出现ali登录之后没有【移动】列不能进行拖拽操作,fff登录之后有【移动】列可以进行拖拽操作。
那么如何给group=3增加testcase模块的updateOrder 方法的权限呢?虽然可以直接操作数据库,但是很不方便,不如在页面操作方便。
所以修改如下:
1、\zentaopms\module\group\lang\resource.php 增加:
$lang->resource->testcase->updateOrder = 'updateOrder';
$lang->testcase->methodOrder[120] = 'updateOrder';
$lang->changelog['9.1'][] = 'testcase-updateOrder';
2、D:\xampp\htdocs\zentaopms\module\testcase\lang\zh-cn.php 增加:
$lang->testcase->updateOrder = '用例拖拽';
那么【组织-权限-某分组(例如group=3的组)-权限维护】页面的效果如下:
我们给group=3这个分组勾选我们刚才加的【用例拖拽】就可以让这个组有调用testcase模块的updateOrder 方法(即可以实现拖拽功能)了。
这个时候再看数据库会发现group=3有updateOrder了这条数据了: