禅道数据的统计【源代码在文末】

6703 / 2025-09-28 12:12:58 世界杯主题歌

项目管理工具很多,我们公司一直用禅道做bug管理,随便把项目管理也搞到禅道上,从需求建立--立项--分任务--执行任务--完成,用的是开源版本,所以少了很多报表,用过一段时间专业版,统计报表数据也不怎么好用,报表都不是自己想要的。

所以自己用python搞了一套统计:

简单模块:

1.各种报表分个类,比如bug的,周报,日报,项目统计等

2.common,处理table,发邮件,链接数据库等

3.sql_script,存放数据库脚本的

贴几个项目代码【需要的拿去用】:

## sql内部用的,数据量不大,没怎么优化,怎么方便怎么写

#BUG每天分布情况

SELECT

z.`部门组`,

z.`被指派`,

CONCAT(

z.提交人,

'(',

t.realname,

')'

) 提交人,

z.`项目名称`,

z.`Bug标题`,

z.Bug状态,

z.提交时间

FROM

(

SELECT

d.`name` 部门组,

CONCAT(

a.assignedTo,

'(',

u.realname,

')'

) 被指派,

a.openedBy 提交人,

a.`name` 项目名称,

CONCAT(a.id, '--', a.title) Bug标题,

CASE

WHEN a.`status` = 'resolved' THEN

'已解决'

WHEN a.`status` = 'active' THEN

'激活'

WHEN a.`status` = 'closed' THEN

'已关闭'

END Bug状态,

a.openedDate 提交时间

FROM

(

SELECT

b.id,

p.`name`,

b.title,

b.`status`,

b.openedBy,

b.openedDate,

CASE

WHEN LENGTH(b.resolvedBy) > 0 THEN

b.resolvedBy

ELSE

b.assignedTo

END assignedTo,

b.resolvedBy

FROM

zt_bug AS b,

zt_project AS p

WHERE

b.openedDate >= CURDATE() # DATE_SUB(CURDATE(), INTERVAL 7 DAY)

AND b.project NOT IN ('107')

AND b.project = p.id

AND b.deleted = '0'

) AS a,

zt_user AS u,

zt_dept AS d

WHERE

a.assignedTo = u.account

AND u.dept = d.id

) AS z,

zt_user AS t

WHERE

z.`提交人` = t.account

ORDER BY

部门组 ASC,

被指派 ASC,

Bug状态 ASC

# -*- coding: UTF-8 -*-

# 表列合并算法

import numpy as np

# 统计相同的列的值及个数

def find_same_column(l, end=0, exc=''):

"""

:param l: 需要计算的列表

:param end: 需要合并的列数(前end列合并),默认为0列计算

:param exc: 列需要排除合并的值,默认为所有值都不合并

:return al: 返回计算好的列表

"""

al = []

for i in range(len(l)):

# if end == 0:

# end = 100000

stop = end

if exc == '':

exc = '!@#$%^&*'

logo = str(exc)

last = ''

num = 1

part = []

for x in range(len(l[i])):

# 只合并列数范围

if i < stop:

# 列值和标识值相同则不合并

if str(l[i][x]) != str(logo):

# 找相同的列值,相等则计数+1

if l[i][x] == last:

num += 1

# 如果列表循环完则append计数

if x + 1 == len(l[i]):

part.append(str(num))

# 如果列值不同则更新last值并重置计数位

else:

# 上一个列表的num没有append,这里append

# 如果是列表第一个则不更新,如果列表上一个值与标识相同也不更新

if x != 0 and str(l[i][x-1]) != str(logo):

part.append(str(num))

last = l[i][x]

part.append(last)

num = 1

# 如果列表循环完append计数

if x+1 == len(l[i]):

part.append(str(num))

# 列表值与标识为相同不合并,直接append

else:

# 还是要判断是否append num

if x != 0 and str(l[i][x-1]) != str(logo):

part.append(str(num))

part.append(l[i][x])

part.append(str(1))

else:

part.append(l[i][x])

part.append(str(1))

al.append(part)

return al

# 处理td标签

def deal_td(l):

"""

:param l: 需要处理td标签的列表

:return al: 返回处理好的列表

"""

al = []

for i in range(len(l)):

part = []

for x in range(0, len(l[i]), 2):

if x == len(l[i]):

break

t_value = str(l[i][x])

t_sum = int(l[i][x+1])

if t_sum >= 2:

for num in range(t_sum):

if num == 0:

part.append('' % str(t_sum) + t_value + '')

else:

part.append('')

else:

part.append('' + t_value + '')

al.append(part)

return al

# 处理tr标签

def deal_tr(l):

"""

:param l: 需要处理tr的列表

:return: 返回处理好的tr字符串

"""

# 倒置列表

td = np.tile(l, 1).T.tolist()

tr = ''

for i in td:

l_tr = ''

for x in range(len(i)):

l_tr += i[x]

s_tr = '' + l_tr + '' + '\n'

tr += s_tr

return tr

# coding = utf-8

# 禅道项目度量--每日bug激活统计

import sys

import datetime

from common import common_mail_test as mail

from common import common_read_sql as read_sql

from common import common_mysql_config as mysql

# 数据获取

def deal_mysql(f):

"""

数据获取与处理

:param f:

:return:

"""

cursor = mysql.db.cursor()

sql = read_sql.read_sql(f)

cursor.execute(sql)

results = cursor.fetchall()

cursor.close()

mysql.db.close()

# tuple类型转换为list类型

li = list(results)

"""

把id相同的数据的放入pl列表,再把列表放入al列表

"""

al = []

pl = []

for i in range(len(li)):

if i == 0:

pl.append(li[i])

# 如果和列表里的名字相同,继续append

if li[i][0] == li[i - 1][0]:

pl.append(li[i])

# 如果不相同,没有到末尾,把当前列表加入al列表,并清空pl列表/i-1 >0 排除i=0情况

if li[i][0] != li[i - 1][0] and i - 1 > 0 and len(pl) != 0:

al.append(pl)

pl = []

if i != len(li) - 1:

# 如果和之前的不同,和之后的也不同,且不是末尾:

if li[i][0] != li[i - 1][0] and i - 1 > 0 and li[i][0] != li[i + 1][0]:

pl.append(li[i])

al.append(pl)

pl = []

# 如果和之前的不同,和之后的相同,且不是末尾:

if li[i][0] != li[i - 1][0] and i - 1 > 0 and li[i][0] == li[i + 1][0]:

pl.append(li[i])

# 如果是末尾

if i == len(li) - 1:

# pl.append(li[i]) # 后来发现重复插入最后一条数据 先注释

al.append(pl)

# 只取满足日期的数据

el = []

for i in al:

for x in i:

if str(x[3]).split(' ')[0] == str(datetime.datetime.now()).split(' ')[0]:

el.append(i)

break

return el

# 处理html

def deal_html(tl):

"""

生成html

:param tl:

:return:

"""

subject = 'BUG激活统计'

head = """

BUG被激活

汇总时间: """ + str(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')) + """

备注:BUG被激活次数大于等于3次

"""

ht = ''

for i in tl:

zj = ''

beg = ''

a = ''

b = ''

c = ''

title = """

""" % (i[0][0], i[0][4])

for x in range(len(i)):

ti = """

"""

if x == 0:

beg = """

""" % (len(i), i[x][0], i[x][1], i[x][2], i[x][3], i[x][5])

else:

a = """

""" % i[x][1]

if i[x][2] == 'activated':

b = """

""" % i[x][2]

else:

b = """

""" % i[x][2]

c = """

""" % (i[x][3], i[x][5])

zj += a + b + c

ho = """

"""

ht += title + ti + beg + zj + ho

end = """

BUG激活情况
BUG标题:

%s

ID 操作人 解决类型 操作时间 备注
%s %s %s %s %s
%s %s %s %s %s
.

--------------------汇总数据源于禅道系统

--------------------

"""

html = head + ht + end

return subject, html

mysql_l = deal_mysql(sys._getframe())

if len(mysql_l) > 0:

s, h = deal_html(mysql_l)

try:

if mail.cs_mail_send(s, h):

print('Send success')

else:

print('Send failure')

except Exception as e:

raise e

else:

print("NO Data !")

统计展示:

配置jenkins定时跑任务执行

源代码下载地址:

https://download.csdn.net/download/tengdakuaijie1/12272565