225 lines
9.0 KiB
Python
225 lines
9.0 KiB
Python
# encoding: UTF-8
|
||
from sqlalchemy import func, cast, Date
|
||
|
||
from ..model.bugModel import Bug, BugComment, BugHistory
|
||
from ..model.userModel import User
|
||
from ..model.caseModel import Module
|
||
from logger import logger
|
||
|
||
|
||
class BugDao(object):
|
||
@staticmethod
|
||
def create(session, model_cls, add_info):
|
||
obj = model_cls(**add_info)
|
||
session.add(obj)
|
||
err = session.done(close=False)
|
||
if err:
|
||
logger.warning(f'{model_cls.__name__}新增失败!{err}')
|
||
return 0, f'新增失败!{err}'
|
||
return obj.id, ''
|
||
|
||
@staticmethod
|
||
def update_by_id(session, model_cls, obj_id, update_info, soft_delete=True):
|
||
filters = [model_cls.id == int(obj_id)]
|
||
if soft_delete and hasattr(model_cls, 'is_delete'):
|
||
filters.append(model_cls.is_delete == 0)
|
||
update_res = session.query(model_cls).filter(*filters).update(update_info)
|
||
err = session.done(close=False)
|
||
if err:
|
||
logger.error(f'{model_cls.__name__}更新失败!id: {obj_id}, err: {err}')
|
||
return 0, f'更新失败!{err}'
|
||
if not update_res:
|
||
return 0, '未查询到对应记录!'
|
||
return int(obj_id), ''
|
||
|
||
@staticmethod
|
||
def get_by_id(session, model_cls, obj_id, soft_delete=True):
|
||
filters = [model_cls.id == int(obj_id)]
|
||
if soft_delete and hasattr(model_cls, 'is_delete'):
|
||
filters.append(model_cls.is_delete == 0)
|
||
return session.query(model_cls).filter(*filters).first()
|
||
|
||
@staticmethod
|
||
def list_by_filters(session, model_cls, filter_list, page=1, limit=20, order_column=None, asc=False):
|
||
query = session.query(model_cls).filter(*filter_list)
|
||
if hasattr(model_cls, 'is_delete'):
|
||
query = query.filter(model_cls.is_delete == 0)
|
||
total = query.count()
|
||
if order_column is not None:
|
||
query = query.order_by(order_column.asc() if asc else order_column.desc())
|
||
rets = query.offset((int(page) - 1) * int(limit)).limit(int(limit)).all()
|
||
return rets, total
|
||
|
||
@staticmethod
|
||
def delete_by_id(session, model_cls, obj_id):
|
||
return BugDao.update_by_id(session, model_cls, obj_id, {'is_delete': 1})
|
||
|
||
@staticmethod
|
||
def generate_bug_key(session):
|
||
max_key = session.query(func.max(Bug.bug_key)).filter(Bug.bug_key.like('BUG-%')).scalar()
|
||
if max_key:
|
||
num = int(max_key.split('-')[1]) + 1
|
||
else:
|
||
num = 1
|
||
return f'BUG-{num:03d}'
|
||
|
||
@staticmethod
|
||
def get_comments(session, bug_id):
|
||
return session.query(BugComment).filter(
|
||
BugComment.bug_id == int(bug_id),
|
||
BugComment.is_delete == 0
|
||
).order_by(BugComment.created_time.desc()).all()
|
||
|
||
@staticmethod
|
||
def get_history(session, bug_id):
|
||
return session.query(BugHistory).filter(
|
||
BugHistory.bug_id == int(bug_id)
|
||
).order_by(BugHistory.created_time.desc()).all()
|
||
|
||
@staticmethod
|
||
def add_history(session, bug_id, field_name, old_value, new_value, operator_id):
|
||
session.add(BugHistory(
|
||
bug_id=bug_id,
|
||
field_name=field_name,
|
||
old_value=str(old_value) if old_value else None,
|
||
new_value=str(new_value) if new_value else None,
|
||
operator_id=operator_id
|
||
))
|
||
err = session.done(close=False)
|
||
if err:
|
||
logger.warning(f'BugHistory新增失败!{err}')
|
||
return False
|
||
return True
|
||
|
||
@staticmethod
|
||
def get_stats(session, product_id=None, project_id=None):
|
||
query = session.query(Bug).filter(Bug.is_delete == 0)
|
||
if product_id:
|
||
query = query.filter(Bug.product_id == int(product_id))
|
||
if project_id:
|
||
query = query.filter(Bug.project_id == int(project_id))
|
||
|
||
total = query.count()
|
||
new_count = query.filter(Bug.status == 0).count()
|
||
pending_count = query.filter(Bug.status == 1).count()
|
||
in_progress_count = query.filter(Bug.status == 2).count()
|
||
resolved_count = query.filter(Bug.status == 3).count()
|
||
closed_count = query.filter(Bug.status == 4).count()
|
||
rejected_count = query.filter(Bug.status == 5).count()
|
||
|
||
by_status = {}
|
||
for status in range(6):
|
||
by_status[str(status)] = query.filter(Bug.status == status).count()
|
||
|
||
by_solution = {}
|
||
solution_results = session.query(
|
||
Bug.solution, func.count(Bug.id)
|
||
).filter(Bug.is_delete == 0)
|
||
if product_id:
|
||
solution_results = solution_results.filter(Bug.product_id == int(product_id))
|
||
if project_id:
|
||
solution_results = solution_results.filter(Bug.project_id == int(project_id))
|
||
solution_results = solution_results.filter(Bug.solution.isnot(None)).group_by(Bug.solution).all()
|
||
for solution, count in solution_results:
|
||
by_solution[solution] = count
|
||
|
||
by_reporter = {}
|
||
reporter_results = session.query(
|
||
User.real_name, func.count(Bug.id)
|
||
).join(User, Bug.reporter_id == User.id).filter(Bug.is_delete == 0)
|
||
if product_id:
|
||
reporter_results = reporter_results.filter(Bug.product_id == int(product_id))
|
||
if project_id:
|
||
reporter_results = reporter_results.filter(Bug.project_id == int(project_id))
|
||
reporter_results = reporter_results.group_by(User.real_name).all()
|
||
for name, count in reporter_results:
|
||
by_reporter[name] = count
|
||
|
||
by_assignee = {}
|
||
assignee_results = session.query(
|
||
User.real_name, func.count(Bug.id)
|
||
).outerjoin(User, Bug.assignee_id == User.id).filter(Bug.is_delete == 0)
|
||
if product_id:
|
||
assignee_results = assignee_results.filter(Bug.product_id == int(product_id))
|
||
if project_id:
|
||
assignee_results = assignee_results.filter(Bug.project_id == int(project_id))
|
||
assignee_results = assignee_results.group_by(User.real_name).all()
|
||
for name, count in assignee_results:
|
||
by_assignee[name or '未指派'] = count
|
||
|
||
by_resolver = {}
|
||
resolver_results = session.query(
|
||
User.real_name, func.count(Bug.id)
|
||
).outerjoin(User, Bug.resolved_by == User.id).filter(Bug.is_delete == 0)
|
||
if product_id:
|
||
resolver_results = resolver_results.filter(Bug.product_id == int(product_id))
|
||
if project_id:
|
||
resolver_results = resolver_results.filter(Bug.project_id == int(project_id))
|
||
resolver_results = resolver_results.group_by(User.real_name).all()
|
||
for name, count in resolver_results:
|
||
by_resolver[name or '未解决'] = count
|
||
|
||
by_module = {}
|
||
module_results = session.query(
|
||
Module.name, func.count(Bug.id)
|
||
).outerjoin(Module, Bug.module_id == Module.id).filter(Bug.is_delete == 0)
|
||
if product_id:
|
||
module_results = module_results.filter(Bug.product_id == int(product_id))
|
||
if project_id:
|
||
module_results = module_results.filter(Bug.project_id == int(project_id))
|
||
module_results = module_results.group_by(Module.name).all()
|
||
for name, count in module_results:
|
||
by_module[name or '未分类'] = count
|
||
|
||
by_version = {}
|
||
version_results = session.query(
|
||
Bug.resolve_version, func.count(Bug.id)
|
||
).filter(Bug.is_delete == 0)
|
||
if product_id:
|
||
version_results = version_results.filter(Bug.product_id == int(product_id))
|
||
if project_id:
|
||
version_results = version_results.filter(Bug.project_id == int(project_id))
|
||
version_results = version_results.filter(Bug.resolve_version.isnot(None)).group_by(Bug.resolve_version).all()
|
||
for version, count in version_results:
|
||
by_version[version] = count
|
||
|
||
by_activation = {}
|
||
|
||
daily_new = {}
|
||
daily_new_results = session.query(
|
||
cast(Bug.created_time, Date).label('stat_date'),
|
||
func.count(Bug.id)
|
||
).filter(Bug.is_delete == 0)
|
||
if product_id:
|
||
daily_new_results = daily_new_results.filter(Bug.product_id == int(product_id))
|
||
if project_id:
|
||
daily_new_results = daily_new_results.filter(Bug.project_id == int(project_id))
|
||
daily_new_results = daily_new_results.group_by('stat_date').order_by('stat_date').all()
|
||
for date, count in daily_new_results:
|
||
daily_new[str(date)] = count
|
||
|
||
daily_resolved = {}
|
||
|
||
daily_closed = {}
|
||
|
||
return {
|
||
'total': total,
|
||
'new': new_count,
|
||
'pending': pending_count,
|
||
'in_progress': in_progress_count,
|
||
'resolved': resolved_count,
|
||
'closed': closed_count,
|
||
'rejected': rejected_count,
|
||
'by_status': by_status,
|
||
'by_solution': by_solution,
|
||
'by_reporter': by_reporter,
|
||
'by_assignee': by_assignee,
|
||
'by_resolver': by_resolver,
|
||
'by_module': by_module,
|
||
'by_version': by_version,
|
||
'by_activation': by_activation,
|
||
'daily_new': daily_new,
|
||
'daily_resolved': daily_resolved,
|
||
'daily_closed': daily_closed
|
||
}
|