Files
effekt-interface/app/api/dao/bugDao.py
2026-05-07 19:21:19 +08:00

225 lines
9.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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
}