魔改!让“禅道”拥有 抄送列表

禅道是第一款国产的开源项目管理软件,她的核心管理思想基于敏捷方法scrum,内置了产品管理和项目管理。
官方传送门:https://www.zentao.net/
禅道有多个版本:专业版、企业版、集团版、开源版。
在使用禅道开源版的过程中,发现了一个问题(不确定是不是使用方式不对),就是禅道的抄送数据并没有在列表中可以展现。

所以摸索了一下实现了以下功能:

  1. 产品->需求列表加入“抄送给我”的需求列表
  2. 测试->BUG列表加入“抄送给我”的BUG列表

1. 参考文档

禅道使用自主开发的zentaophp框架开发,内置了完整的扩展机制(非简单的钩子),用户可以非常方便的对禅道进行彻底的二次开发。
zentaophp开发手册地址:https://devel.easycorp.cn/book/zentaophphelp/about-10.html
zentaophp二次开发文档地址:https://devel.easycorp.cn/book/extension/intro-45.html

2. 流程分析

zentaophp的请求分发是按url地址来划分的,比如/product-browse-1.html这个请求。
其中:product是一个模块,而browse是这个模块control的一个接口。
以BUG列表为例:
control的browse接口接收到http请求后调用model的getBugs方法拉取bugs数据,然后将数据填充到/view/browse.html.php视图中显示出来。

bug

需求的流程大致是一样的,不过需求的入口是product模块,然后通过调用story拉取数据。

3. 拓展功能

zentaoPHP框架每个模块按照mvc进行划分,有自己的control(控制层)、 model(模型层)和view(视图层),并且提供了非常便利的拓展方式。
想要拓展自己的功能只需要将拓展代码放在每个模块的ext目录下即可,可以看一下效果图:
拓展前:
old
拓展后:
new

a. 对视图层进行拓展

为了不改变禅道的源码,对视图层的拓展钩子进行扩展,钩子脚本的命名规则为方法名. 扩展名.html.hook.php。
所以对应的拓展页面名称为:browse.mailto.html.hook.php,存放路径为:module/bug/ext/view。内容如下:

<script>
  <?php
  $mail_to_type = 'mailtome';
  $mail_to_label = "<span class='text'>抄送给我</span>";
  $mail_to_active = $mail_to_type == $browseType ? 'btn-active-text' : '';
  $mail_to_uri = html::a($this->createLink('bug', 'browse', "productid=$productID&branch=$branch&browseType=$mail_to_type"), $mail_to_label, "", "class='btn btn-link $mail_to_active'");
  $mail_to_uri = str_replace(array("\r", "\n", "\r\n"), "", $mail_to_uri);
  ?>
  $('#bysearchTab')
    .parent()
    .find('a:eq(3)')
    .after("<?php echo $mail_to_uri ?>");
</script>

通过zentaoPHP的js模块生成a标签,如果将a标签用jQuery插入到指定的位置。

b. 对模型层进行拓展

上面视图层拓展中,“抄送给我”调用的还是bug模块的browse接口,所以不需要对control进行拓展,只需要重写model的getBugs方法,添加对browseType=‘mailtome’的数据进行处理即可。

重写getBugs方法,拓展文件名称以getBugs方法名称命名,路径为module/bug/ext/model/,内容如下:

<?php
public function getBugs($productID, $projects, $branch, $browseType, $moduleID, $queryID, $sort, $pager)
{
  if($browseType == 'mailtome')
  {
    /* Set modules and browse type. */
    $modules    = $moduleID ? $this->loadModel('tree')->getAllChildId($moduleID) : '0';
    $browseType = ($browseType == 'bymodule' and $this->session->bugBrowseType and $this->session->bugBrowseType != 'bysearch') ? $this->session->bugBrowseType : $browseType;
    $bugs = array();
    $bugs = $this->getMailToMeBugs($productID, $branch, $modules, $projects, $sort, $pager);
    return $this->checkDelayBugs($bugs);
  } 
  else 
  {
    return parent::getBugs($productID, $projects, $branch, $browseType, $moduleID, $queryID, $sort, $pager);
  }
}
?>

这里,如果$browseType='mailtome'的话,就调用getMailToMeBugs这个方法,否则调用父级的getBugs方法。
getMailToMeBug这个方法是自己拓展的,所有需要在module/bug/ext/model/路径下创建对应的php,内容如下:

<?php
public function getMailToMeBugs($productID, $branch, $modules, $projects, $orderBy, $pager)
{
    return $this->dao->select('*')->from(TABLE_BUG)
      ->where('project')->in(array_keys($projects))
      ->andWhere('product')->eq($productID)
      ->beginIF($branch)->andWhere('branch')->in($branch)->fi()
      ->beginIF($modules)->andWhere('module')->in($modules)->fi()
      ->andWhere('deleted')->eq(0)
      ->andWhere('mailto', true)->like('%,' . $this->app->user->account . ',%')
      ->orWhere('mailto')->like('%,' . $this->app->user->account)
      ->markRight(1)
      ->andWhere('status')->eq('active')
      ->orderBy($orderBy)->page($pager)->fetchAll();
}
?>

根据禅道的抄送入库规则“,账号”,只需要查询“,账号,”“,账号”的数据即可,这里只查询状态为激活的BUG。

c. 拓展需求“抄送给我”列表

需求“抄送给我”的拓展方式跟BUG“抄送给我”的拓展方式是一样的,需要注意的是需求入口是product模块,拉取的数据是story模块。

story拓展的model代码:

<?php
public function getByMailTo($productID, $branch, $modules, $orderBy, $pager)
{
  $stories = $this->dao->select('*')->from(TABLE_STORY)
    ->where('product')->in($productID)
    ->andWhere('deleted')->eq(0)
    ->beginIF($branch)->andWhere("branch")->eq($branch)->fi()
    ->beginIF($modules)->andWhere("module")->in($modules)->fi()
    ->andWhere('mailto', true)->like('%,' . $this->app->user->account . ',%')
    ->orWhere('mailto')->like('%,' . $this->app->user->account)
    ->markRight(1)
    ->andWhere('stage')->ne('closed')
    ->orderBy($orderBy)
    ->page($pager)
    ->fetchAll();
  return $this->mergePlanTitle($productID, $stories, $branch);
}
?>

下面是拓展后的效果:

story

至此,就可以在禅道上查看“抄送给我”的需求和BUG了。

我是写java的,不会php代码,这里的代码都是根据开发手册依葫芦画瓢的。

=========================================================
源码可关注公众号 “HiIT青年” 发送 “zentao” 获取。(如果没有收到回复,可能是你之前取消过关注。)

HiIT青年

关注公众号,阅读更多文章。

posted @ 2020-07-25 10:44  HiIT青年  阅读(1883)  评论(0编辑  收藏  举报