一、背景及痛点分析
禅道版本
旗舰版 Max7.1
现有报告功能的不足
周报:仅覆盖短期数据,缺乏迭代整体视角。
里程碑报告:混合历史迭代数据,无法清晰聚焦当月迭代成果。
实际需求场景
团队需要按月统计单一迭代的完整数据(如需求完成率、缺陷分布、工时效率等)。
避免历史数据干扰,快速生成管理层所需的阶段性总结。
二、功能设计目标
核心需求
独立展示当月迭代的统计维度(与周报/里程碑隔离),在项目-报告添加一栏月报页面。
支持自定义统计数据。
三、功能实现
二次开发相关代码都放在/extension/custom下面,文末有相关的参考链接,这里不过多赘述,主要包括了monthly模块代码,菜单配置以及左侧下拉框配置代码
核心代码
- 菜单配置
<?php
$lang->navGroup->monthly = 'project';
$lang->monthly = new stdclass();
$lang->monthly->index = '月报';
$lang->waterfall->menu->weekly = array('link' => "{$lang->project->report}|weekly|index|project=%s", 'subModule' => ',monthly,milestone,');
$lang->waterfall->menu->weekly['subMenu'] = new stdclass();
$lang->waterfall->menu->weekly['subMenu']->index = "{$lang->project->report}|weekly|index|project=%s";
$lang->waterfall->menu->weekly['subMenu']->monthly = "{$lang->monthly->index}|monthly|index|project=%s";
$lang->waterfall->menu->weekly['subMenu']->milestone = '里程碑报告|milestone|index|project=%s';
$lang->waterfall->menu->weekly['menuOrder'][5] = 'index';
$lang->waterfall->menu->weekly['menuOrder'][6] = 'monthly';
$lang->waterfall->menu->weekly['menuOrder'][10] = 'milestone';
- 下拉框配置
<?php
// config/zentaopms.php 左侧下拉框权限添加monthly-index
$config->hasSwitcherMethods = array('monthly-index', 'project-bug', 'project-testcase', 'execution-bug', 'execution-testcase', 'testtask-cases', 'testtask-view', 'testtask-report', 'testtask-groupcase', 'testtask-linkcase');
// $config->hasSwitcherModules = array('monthly', 'design');
- control.php
<?php
class monthly extends control
{
public function __construct()
{
parent::__construct();
$this->view->users = $this->loadModel('user')->getPairs('noletter');
}
/**
* Common action.
*
* @param int $projectID
* @access public
* @return void
*/
public function commonAction($projectID = 0, $executionID = 0, $executions)
{
$this->loadModel('project');
$this->project->setMenu($projectID);
$this->view->title = $this->lang->monthly->title;
$this->view->projectID = $projectID;
$this->view->executionID = $executionID;
$this->view->executions = $executions;
$this->view->switcherParams = "projectID={$projectID}&executionID={$executionID}";
$this->view->switcherText = isset($executions[$executionID]) ? $executions[$executionID]->name : $this->lang->execution->allExecutions;
$this->view->switcherObjectID = $executionID;
if(empty($executions)) $this->config->excludeSwitcherList[] = 'monthly-index';
}
/**
* 项目月报首页
*
* @param int $projectID
* @access public
* @return void
*/
public function index($projectID = 0, $executionID = 0)
{
$this->loadModel('execution');
// 默认为项目最新执行
$executions = $this->execution->getList($projectID);
if ($executionID == 0 && !empty($executions))
{
$executionID = reset($executions)->id;
}
$this->commonAction($projectID, $executionID, $executions);
/* Get report data from module and assign data to view object. */
$data = $this->monthly->getReportData($projectID, $executionID);
foreach($data as $key => $val) $this->view->$key = $val;
$this->display();
}
/**
* Ajax get execution drop menu.
*
* @param int $projectID
* @param int $executionID
* @access public
* @return void
*/
public function ajaxSwitcherMenu($projectID, $executionID)
{
$this->view->link = helper::createLink('monthly', 'index', "projectID={$projectID}&executionID={id}");
$this->view->projectID = $projectID;
$this->view->executionID = $executionID;
$this->view->executions = $this->loadModel('execution')->getList($projectID);
$this->display();
}
}
四、实现效果
点击项目-报告-月报进入项目迭代总结报告页面,默认展示最新一次执行的数据,可以通过左侧下拉框切换执行
五、遇到的问题
这里主要说一下遇到的一些主要问题:
- 页面主体内容被撑开到底部
我在开发monthly模块时参考的禅道内置周报weekly模块的代码,前端采用html+拼接php代码的方式实现前端页面,采用这种方式会导致页面主体内容被撑开到底部。
解决方法:采用zin的方式编写前端代码 - 左侧下拉框列表
这里我找了半天实现方式,终于发现需要进行额外配置,$config->hasSwitcherModules = array(‘monthly’, ‘design’);将我们添加的模块加进去,然后参考项目-设计模块,实现对应control.php的ajaxSwitcherMenu方法,以及ui/ajaxswitchermenu.html.php即可
参考链接:
关于zentaoPHP框架
禅道二次开发简介
禅道二次开发讲解
ZIN框架