所有人的任务都是在不断滚动的,每个人每天都面临至少四种任务:
- 计划性任务(长期)
- 插入性任务(长期或短期,紧急)
- 线上问题(重要紧急短期)
- Bug问题(重要不紧急)
所以作为管理人员要管理好研发资源就要妥善的协调任务安排,而且时候还要针对任务变更情况进行分析,对内部人员或者外部需求单位提出改进需求。
这是一个管理需求,基于人员视角,观察一段时间区间内某个人员的任务变化情况并进行分析。
由于观察的区间并不确定,所以我们要将每个人每天的未完成子任务缓存,并且根据页面需要获取指定时间区间的子任务聚合。
先给出最终效果:

我们要做的事情:
- 定时任务用于每天定时保存未完成子任务
- 后台服务根据前端传入条件查询并且聚合任务信息
- 前端展示
定时任务使用python作为脚本,使用crontab凌晨执行,每次都以日期作为表名新保存一个表,脚本实际上使用人员任务排期管理中的sql,用 create table z_subtask_%date () 包起来就OK了。
服务端还是使用上面的python启动的web服务,增加一个接口。
最终界面主要视角为人员,字段包括:
- 主任务和子任务的信息
- 何时创建(确认何时接收到任务)
- 开始日期和结束日期,如果日期从未变化过则是一个日期,如果有调整则是日期区间
- 持续天数,是指这个任务有缓存在多少天的库中,即新建之后持续了多少天
- 最终状态,是指到查询截止日期这天,这个任务是否完成
这样我们能够基本来分析某个人员他的任务计划性和延迟性,沟通了解原因并且制定相应的优化方案。
每个组织一定会有分析需求,无论是内部改进或者整体汇报,能够有图表和数据表的完整呈现是最基本的要求。这个需求最早是尝试在Jira的插件中来寻找的,但是尝试了不少插件发现都达不到预期的效果,最终只能转入了使用第三方BI框架,底层数据源自己组织。
选定的就是阿里云的QuickBI。
展示一部分效果图:
工时维度BI报表

迭代任务分析

有了BI工具,实际上报表制作成什么样就没有太大约束了。基本主要还是针对工时、迭代任务两部分的分析。
我提供给大家两份sql参考Jira的底层数据库组织数据的示例:
迭代任务组织:
select concat('C_', a.id) as pissueId,
concat("EXEPD-", a.issuenum) as ikey,
k.pname as itype,
a.SUMMARY,
sum(
(ifnull(a.TIMESPENT, 0) + ifnull(j.TIMESPENT, 0)) / 3600) as allTimeSpent,
sum(ifnull(ll.timeworked, 0)) / 3600 as cuMonthTimeSpent,
b.pname,
ifnull(ifnull((case when i.vname='hotfix' then null else i.vname end) , e.customvalue), '版本为空') as vname,
1 as nums
from jiraissue a
join issuestatus b on b.ID = a.issuestatus
left join nodeassociation f on f.SOURCE_NODE_ID = a.ID and f.ASSOCIATION_TYPE = 'IssueFixVersion'
left join projectversion i on i.ID = f.SINK_NODE_ID
left join customfield c on c.cfname = '修正状态'
left join customfieldvalue d on d.CUSTOMFIELD = c.id and d.ISSUE = a.ID
left join customfieldoption e on e.CUSTOMFIELD = c.ID and e.id = d.STRINGVALUE
left join issuelink g on g.SOURCE = a.ID and g.LINKTYPE = 10100
left join jiraissue j on j.ID = g.DESTINATION
join issuetype k on k.id = a.issuetype
left join (select l.issueid, sum(ifnull(l.timeworked, 0)) as timeworked
from worklog l
where date_format(l.STARTDATE, '%Y-%m') = '2019-06'
group by l.issueid) ll on ll.issueid = j.ID
where a.issuenum in (1,2,3,4)
and a.PROJECT = 10000
group by a.ID
工时分析:
select a.id,
a.issueid,
concat('C_', ifnull(n.SOURCE, a.id)) as pissueId,
a.worklogbody,
(a.timeworked / 3600) as wmin,
(a.timeworked / 3600 / (case d.lower_parent_name
when 'org-pd-qa' then 10
when 'org-pd-frontside-h5' then 9
when 'org-pd-frontside-native' then 5
when 'org-pd-serverside-b' then 12
when 'org-pd-serverside-a' then 7
when 'org-pd-product' then 9
else '' end)) as wminperm,
date_format(a.STARTDATE, '%Y-%m-%d') as sdate,
date_format(a.STARTDATE, '%Y-%m') as sdm,
c.last_name,
(case d.lower_parent_name
when 'org-pd-qa' then '测试'
when 'org-pd-frontside-h5' then '前端h5'
when 'org-pd-frontside-native' then '原生'
when 'org-pd-serverside-b' then '业务'
when 'org-pd-serverside-a' then '架构'
when 'org-pd-product' then '产品UI'
else '' end) as deptname,
k.pname,
concat(h.pkey, '-', e.issuenum) as issuekey,
concat('https://jira.exexm.com/browse/', h.pkey, '-', e.issuenum) as issueurl,
(case j.pname when 'Sub-task' then '任务与子任务' when 'Task' then '任务与子任务' else j.pname end) as issuetypename,
e.SUMMARY,
i.vname,
(case
(i.vname is null and (l.STRINGVALUE is not null or ll.STRINGVALUE is not null))
then 'hotfix'
(i.vname is null or i.vname='')
then '版本为空'
a.issueid = 10752
then '日常事务'
a.issueid = 18019
then '规划外事务'
else i.vname end) as cord
from worklog a
join app_user b on b.user_key = a.AUTHOR
join cwd_user c on c.lower_user_name = b.lower_user_name
join cwd_membership d on d.lower_child_name = b.lower_user_name and d.lower_parent_name in
('org-pd-frontside-h5',
'org-pd-frontside-native',
'org-pd-serverside-a',
'org-pd-serverside-b',
'org-pd-qa',
'org-pd-product')
join jiraissue e on e.ID = a.issueid
left join nodeassociation f on f.SOURCE_NODE_ID = e.ID and f.ASSOCIATION_TYPE = 'IssueFixVersion'
left join projectversion i on i.ID = f.SINK_NODE_ID
join issuetype j on j.id = e.issuetype
join project h on h.ID = e.PROJECT
left join issuelink n on n.DESTINATION = e.ID and n.LINKTYPE = 10100
join issuestatus k on k.ID = e.issuestatus
left join customfieldvalue l on l.CUSTOMFIELD = 10025 and l.ISSUE = n.SOURCE
left join customfieldoption m on m.CUSTOMFIELD = 10025 and m.id = l.STRINGVALUE
left join customfieldvalue ll on ll.CUSTOMFIELD = 10025 and ll.ISSUE = e.ID
left join customfieldoption mm on mm.CUSTOMFIELD = 10025 and mm.id = ll.STRINGVALUE
where a.STARTDATE >= '2019-1-1'
order by a.STARTDATE asc
写到这里,所有关于Jira的使用的整理目前告一段落了。但是这应该还只是一个阶段性里程碑而已,我们的组织架构在进步,过程管理方法在进步,Atlassian也在进步,所以我们也不能停下自己的脚步。Jira还只是完整生态当中的一个环节,我们要更好的组织我们的研发团队,后面还有一些伙伴给大家介绍。一个企业、研发团队要能长久的生存和提高,就需要积累,但是不能口口相传,还要能进行阶段性的梳理和提高。下一章就是企业如何使用Confluence进行知识积累。
到现在已经写到了第五章节,实际上离Jira的官方系统已经越来越远,本章节的内容基本上已经完全脱离了Jira这个系统本身,而是依赖Jira的API接口和数据库进行开发了。主要包含如下几个功能:人员任务排期管理历史人员任务排期检查BI报表注意:由于我们的二次开发基本都是做成静态页面,但是大量使用了Jira的API接口,为了能够方便的使用。所以我们将这些页面放到Jira的容器当中,在其中建...
1、JIRA REST API测试样例https://developer.atlassian.com/server/jira/platform/jira-rest-api-examples/
2、JIRA API说明文档https://developer.atlassian.com/cloud/jira/platform/rest/v2/
3、JIRA JQL语法说明https:...
最近在折腾Jira的二次开发,说实话,二次开发需要对系统的架构有一定的了解才好下手。虽然Jira这个产品很完善,官方有很详细的文档供开发者参考,但小弟还是花了不少时间研究,开发了近一个月的时间,现在把一些用到的知识和问题整理出来,与大家分享。
这次开发主要是做一个中间件,用来连接jira系统和其他系统从而实现系统之间的相互的通信,如创建一个问题(Issue),对jira里一些问题(即Issu
jira工作流有哪些最佳集成可以用来优化JIRA工作流程?
我喜欢寻找在工作流程中提高效率的方法。 看着那些小的自动化和流畅的流程,使我的脸上露出笑容。 我知道我并不孤单,有时花了更多的时间来使正常工作变得很少,而最终却节省了我。
好东西xkcd在这里对我来说!
幸运的是,并非所有优化都如此繁重。 查找工作流增强的一种好方法是查看正在使用的工具之间的可能集成。 一个很好的起点是...
C#: https://github.com/techtalk/JiraRestClient
Modifying JiraRestClient:http://www.31a2ba2a-b718-11dc-8314-0800200c9a66.com/2016/01/
Jira:https://bitbucket.org/atlassian/atlassian-connect-spring-boot/src/mas...
Jira二次开发感受
白天一直关心大家的缺陷和项目进度,到家后有开始搞起了jira的二次开发,虽然照着它网站上的例子一步一步的做(这点也是我们产品需要学习的地方),但总体感觉陷阱重重.
环境就搞了3天左右,编写helloworld又用了3天,结论又是一堆科学怪人编出了的东西。想想你提供的是二次开发框架,而不是所有的编程框架和技术,一会儿配置、一会儿serverlet,幸亏搞过ja
有没有会jira二次开发的博主加我微信,我这边有个项目可以分包,做私活,我微信971151554@TOC
有没有会jira二次开发的博主加我微信,我这边有个项目可以分包,做私活,我微信971151554