增加项目的各个功能

This commit is contained in:
qiaoxinjiu
2026-05-07 19:21:19 +08:00
parent aba1618f89
commit ee6cd4ae66
121 changed files with 9346 additions and 43 deletions

View File

@@ -0,0 +1,325 @@
# encoding: UTF-8
import os
import uuid
from datetime import datetime
from flask import current_app
from .baseCrudController import BaseCrudController
from ..model.bugModel import Bug, BugComment
from ..model.productModel import Product
from ..model.projectModel import Project
from ..model.userModel import User
from ..model.caseModel import Module
from ..service.bugService import BugService
from ..service.userService import UserService
class BugUploadController(BaseCrudController):
UPLOAD_FOLDER = 'attachment/bug_picture'
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif', 'bmp'}
def allowed_file(self, filename):
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in self.ALLOWED_EXTENSIONS
def bug_upload(self):
if 'file' not in self.req_data.files:
return '', '未找到上传文件'
file = self.req_data.files['file']
if file.filename == '':
return '', '文件名不能为空'
if not self.allowed_file(file.filename):
return '', '不支持的文件格式仅支持png, jpg, jpeg, gif, bmp'
try:
os.makedirs(self.UPLOAD_FOLDER, exist_ok=True)
timestamp = datetime.now().strftime('%Y%m%d%H%M%S')
ext = file.filename.rsplit('.', 1)[1].lower()
new_filename = f'bug-{timestamp}-{uuid.uuid4().hex[:8]}.{ext}'
file_path = os.path.join(self.UPLOAD_FOLDER, new_filename)
file.save(file_path)
file_url = f'/uploads/{new_filename}'
return file_url, ''
except Exception as e:
return '', f'文件上传失败:{str(e)}'
class BugController(BaseCrudController):
def bug_list(self):
filters = []
product_id = self._get(self.req_data, 'productId', 'product_id')
project_id = self._get(self.req_data, 'projectId', 'project_id')
module_id = self._get(self.req_data, 'moduleId', 'module_id')
bug_type = self._get(self.req_data, 'bugType', 'bug_type')
severity = self._get(self.req_data, 'severity')
priority = self._get(self.req_data, 'priority')
status = self._get(self.req_data, 'status')
assignee_id = self._get(self.req_data, 'assigneeId', 'assignee_id')
reporter_id = self._get(self.req_data, 'reporterId', 'reporter_id')
resolved_by = self._get(self.req_data, 'resolvedBy', 'resolved_by')
reproduce_rate = self._get(self.req_data, 'reproduceRate', 'reproduce_rate')
keyword = self._get(self.req_data, 'keyword')
if product_id:
filters.append(Bug.product_id == int(product_id))
if project_id:
filters.append(Bug.project_id == int(project_id))
if module_id:
filters.append(Bug.module_id == int(module_id))
if bug_type not in (None, ''):
filters.append(Bug.bug_type == int(bug_type))
if severity not in (None, ''):
filters.append(Bug.severity == int(severity))
if priority not in (None, ''):
filters.append(Bug.priority == int(priority))
if status not in (None, ''):
filters.append(Bug.status == int(status))
if assignee_id:
filters.append(Bug.assignee_id == int(assignee_id))
if reporter_id:
filters.append(Bug.reporter_id == int(reporter_id))
if resolved_by:
filters.append(Bug.resolved_by == int(resolved_by))
if reproduce_rate not in (None, ''):
filters.append(Bug.reproduce_rate == int(reproduce_rate))
if keyword:
filters.append(Bug.title.like(f'%{keyword}%') | Bug.description.like(f'%{keyword}%'))
items, total = BugService.list_by_filters(
self.session, Bug, filters,
self._get(self.req_data, 'pageNo', 'page', default=1),
self._get(self.req_data, 'pageSize', 'size', default=20),
Bug.created_time
)
user_ids = []
for item in items:
if item.assignee_id:
user_ids.append(item.assignee_id)
if item.reporter_id:
user_ids.append(item.reporter_id)
if item.resolved_by:
user_ids.append(item.resolved_by)
user_info_map = UserService.get_user_info_map(self.session, user_ids) if user_ids else {}
result_list = []
for item in items:
bug_dict = item.to_dict()
if item.assignee_id and item.assignee_id in user_info_map:
bug_dict['assignee_name'] = user_info_map[item.assignee_id].get('real_name', '')
else:
bug_dict['assignee_name'] = ''
if item.reporter_id and item.reporter_id in user_info_map:
bug_dict['reporter_name'] = user_info_map[item.reporter_id].get('real_name', '')
else:
bug_dict['reporter_name'] = ''
if item.resolved_by and item.resolved_by in user_info_map:
bug_dict['resolved_by_name'] = user_info_map[item.resolved_by].get('real_name', '')
else:
bug_dict['resolved_by_name'] = ''
result_list.append(bug_dict)
return {'list': result_list, 'total': total}
def bug_detail(self):
bug_id = self._get(self.req_data, 'bugId', 'id')
if not bug_id:
return {}, 'bugId 为必传参数'
item = BugService.get_by_id(self.session, Bug, bug_id)
if not item:
return {}, '未查询到对应 Bug'
ret = self.serialize(item, ['is_delete'])
if item.product_id:
product = self.session.query(Product).filter(Product.id == item.product_id, Product.is_delete == 0).first()
ret['product_name'] = product.name if product else ''
if item.project_id:
project = self.session.query(Project).filter(Project.id == item.project_id, Project.is_delete == 0).first()
ret['project_name'] = project.name if project else ''
if item.reporter_id:
reporter = self.session.query(User).filter(User.id == item.reporter_id, User.is_delete == 0).first()
ret['reporter_name'] = reporter.real_name if reporter else ''
if item.assignee_id:
assignee = self.session.query(User).filter(User.id == item.assignee_id, User.is_delete == 0).first()
ret['assignee_name'] = assignee.real_name if assignee else ''
if item.module_id:
module = self.session.query(Module).filter(Module.id == item.module_id, Module.is_delete == 0).first()
ret['module_name'] = module.name if module else ''
if item.resolved_by:
resolved_by_user = self.session.query(User).filter(User.id == item.resolved_by, User.is_delete == 0).first()
ret['resolved_by_name'] = resolved_by_user.real_name if resolved_by_user else ''
comments = BugService.get_comments(self.session, bug_id)
comment_user_ids = [c.user_id for c in comments if c.user_id]
user_info_map = UserService.get_user_info_map(self.session, comment_user_ids) if comment_user_ids else {}
serialized_comments = []
for comment in comments:
comment_dict = comment.to_dict()
if comment.user_id and comment.user_id in user_info_map:
comment_dict['user_name'] = user_info_map[comment.user_id].get('real_name', '')
else:
comment_dict['user_name'] = ''
serialized_comments.append(comment_dict)
ret['comments'] = serialized_comments
history_items = BugService.get_history(self.session, bug_id)
user_ids = set()
for h in history_items:
if h.operator_id:
user_ids.add(h.operator_id)
if h.field_name in ('assignee_id', 'reporter_id', 'user_id', 'resolved_by'):
if h.old_value:
try:
user_ids.add(int(h.old_value))
except (ValueError, TypeError):
pass
if h.new_value:
try:
user_ids.add(int(h.new_value))
except (ValueError, TypeError):
pass
user_info_map = UserService.get_user_info_map(self.session, list(user_ids)) if user_ids else {}
serialized_history = []
for h in history_items:
h_dict = h.to_dict()
if h.operator_id:
h_dict['operator_id'] = user_info_map.get(h.operator_id, {}).get('real_name', h.operator_id)
if h.field_name in ('assignee_id', 'reporter_id', 'user_id', 'resolved_by'):
if h.old_value:
try:
old_uid = int(h.old_value)
h_dict['old_value'] = user_info_map.get(old_uid, {}).get('real_name', h.old_value)
except (ValueError, TypeError):
pass
if h.new_value:
try:
new_uid = int(h.new_value)
h_dict['new_value'] = user_info_map.get(new_uid, {}).get('real_name', h.new_value)
except (ValueError, TypeError):
pass
serialized_history.append(h_dict)
ret['history'] = serialized_history
return ret, ''
def bug_create(self):
title = self._get(self.req_data, 'title')
product_id = self._get(self.req_data, 'productId', 'product_id')
project_id = self._get(self.req_data, 'projectId', 'project_id')
if not title or not product_id or not project_id:
return 0, 'title、productId、projectId 为必传参数'
bug_key = BugService.generate_bug_key(self.session)
add_info = {
'bug_key': bug_key,
'title': title,
'description': self._get(self.req_data, 'description'),
'bug_type': int(self._get(self.req_data, 'bugType', 'bug_type', default=1)),
'severity': int(self._get(self.req_data, 'severity', default=2)),
'priority': int(self._get(self.req_data, 'priority', default=2)),
'status': 0,
'reporter_id': self._get(self.req_data, 'reporterId', 'reporter_id'),
'assignee_id': self._get(self.req_data, 'assigneeId', 'assignee_id'),
'product_id': product_id,
'project_id': project_id,
'module_id': self._get(self.req_data, 'moduleId', 'module_id'),
'case_id': self._get(self.req_data, 'caseId', 'case_id'),
'plan_id': self._get(self.req_data, 'planId', 'plan_id'),
'environment': self._get(self.req_data, 'environment'),
'steps': self._get(self.req_data, 'steps'),
'solution': self._get(self.req_data, 'solution'),
'resolve_version': self._get(self.req_data, 'resolveVersion', 'resolve_version'),
'resolved_by': self._get(self.req_data, 'resolvedBy', 'resolved_by'),
'reproduce_rate': self._get(self.req_data, 'reproduceRate', 'reproduce_rate'),
'is_delete': 0
}
return BugService.create(self.session, Bug, add_info)
def bug_update(self):
bug_id = self._get(self.req_data, 'bugId', 'id')
if not bug_id:
return 0, 'bugId 为必传参数'
update_info = {}
field_mapping = [
(('title',), 'title'),
(('description',), 'description'),
(('bugType', 'bug_type'), 'bug_type'),
(('severity',), 'severity'),
(('priority',), 'priority'),
(('status',), 'status'),
(('assigneeId', 'assignee_id'), 'assignee_id'),
(('reporterId', 'reporter_id'), 'reporter_id'),
(('moduleId', 'module_id'), 'module_id'),
(('caseId', 'case_id'), 'case_id'),
(('planId', 'plan_id'), 'plan_id'),
(('environment',), 'environment'),
(('steps',), 'steps'),
(('solution',), 'solution'),
(('resolveVersion', 'resolve_version'), 'resolve_version'),
(('resolvedBy', 'resolved_by'), 'resolved_by'),
(('reproduceRate', 'reproduce_rate'), 'reproduce_rate')
]
for req_keys, column_key in field_mapping:
value = self._get(self.req_data, *req_keys)
if value is not None:
update_info[column_key] = value
result = BugService.update_by_id(self.session, Bug, bug_id, update_info)
comment = self._get(self.req_data, 'comment')
user_id = self._get(self.req_data, 'user_id', 'userId')
if comment and user_id:
BugService.add_comment(self.session, bug_id, comment, user_id)
return result
def bug_delete(self):
bug_id = self._get(self.req_data, 'bugId', 'id')
if not bug_id:
return 0, 'bugId 为必传参数'
return BugService.delete_by_id(self.session, Bug, bug_id)
def bug_history_add(self):
bug_id = self._get(self.req_data, 'bugId', 'id')
field_name = self._get(self.req_data, 'fieldName', 'field_name')
old_value = self._get(self.req_data, 'oldValue', 'old_value')
new_value = self._get(self.req_data, 'newValue', 'new_value')
operator_id = self._get(self.req_data, 'operatorId', 'operator_id', 'user_id', 'userId')
if not bug_id:
return 0, 'bugId 为必传参数'
if not field_name:
return 0, 'fieldName 为必传参数'
if not operator_id:
return 0, 'operatorId 为必传参数'
success = BugService.add_history(self.session, bug_id, field_name, old_value, new_value, operator_id)
return 1 if success else 0, '' if success else '添加历史记录失败'
def bug_comment_add(self):
user_id = self._get(self.req_data, 'user_id', 'reporter_id', 'reporterId')
bug_id = self._get(self.req_data, 'bugId')
content = self._get(self.req_data, 'content')
if not bug_id:
return 0, 'bugId 为必传参数'
if not content:
return 0, 'content 为必传参数'
return BugService.add_comment(self.session, bug_id, content, user_id)
def bug_stats(self):
product_id = self._get(self.req_data, 'productId', 'product_id')
project_id = self._get(self.req_data, 'projectId', 'project_id')
return BugService.get_stats(self.session, product_id, project_id)