from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select, update, func, desc, asc from module_admin.system.dao.test_permission_dao import TestPermissionDao from module_admin.system.entity.do.etest_entities_do import TestPermission from module_admin.system.entity.do.test_work_order_do import TestWorkOrder from module_admin.entity.vo.common_vo import CrudResponseModel from utils.common_util import CamelCaseUtil from exceptions.exception import ServiceException from datetime import datetime, date from typing import Optional, List class TestPermissionService: """ 测试权限配置服务层 """ @classmethod async def get_permission_list(cls, db: AsyncSession, query_obj, is_page: bool = False): """获取权限列表""" result = await TestPermissionDao.get_list(db, query_obj, is_page) if is_page: rows, total = result rows_list = [CamelCaseUtil.transform_result(row) for row in rows] return {'rows': rows_list, 'total': total} else: return [CamelCaseUtil.transform_result(row) for row in result] @classmethod async def get_permission_detail(cls, db: AsyncSession, id: int): """获取权限详情""" obj = await TestPermissionDao.get_by_id(db, id) if not obj: raise ServiceException(message='权限配置不存在') return CamelCaseUtil.transform_result(obj) @classmethod async def add_permission(cls, db: AsyncSession, model, current_user_id: int): """新增权限配置""" obj = TestPermission(**model.model_dump(exclude_unset=True)) obj.create_by = current_user_id obj.create_time = datetime.now() obj.update_time = datetime.now() await TestPermissionDao.add(db, obj) await db.commit() return CrudResponseModel(is_success=True, message='新增成功') @classmethod async def edit_permission(cls, db: AsyncSession, model, current_user_id: int): """编辑权限配置""" obj = await TestPermissionDao.get_by_id(db, model.id) if not obj: raise ServiceException(message='权限配置不存在') model.update_by = current_user_id model.update_time = datetime.now() await TestPermissionDao.update(db, model) await db.commit() return CrudResponseModel(is_success=True, message='更新成功') @classmethod async def delete_permission(cls, db: AsyncSession, ids: str, current_user_id: int): """删除权限配置""" id_list = [int(id_str) for id_str in ids.split(',')] await TestPermissionDao.delete(db, id_list) await db.commit() return CrudResponseModel(is_success=True, message='删除成功') class WorkOrderClaimService: """ 工单领取服务层 """ @classmethod async def claim_work_order(cls, db: AsyncSession, current_user_id: int): """ 测试人员领取工单 排序规则: 优先级高 > 截止日期近 """ # 1. 获取用户权限 permissions = await TestPermissionDao.get_by_user_id(db, current_user_id) if not permissions: raise ServiceException(message='您没有测试权限') # 2. 检查当前负载 current_load_result = await db.execute( select(func.count()).select_from(TestWorkOrder).where( TestWorkOrder.tester_id == current_user_id, TestWorkOrder.test_status.in_([0, 1]), # 待测试或测试中 TestWorkOrder.del_flag == '0' ) ) current_load = current_load_result.scalar() max_load = permissions[0].max_concurrent if permissions else 5 if current_load >= max_load: raise ServiceException(message=f'您已达到最大并行工单数限制({max_load})') # 3. 查询可领取工单(按优先级降序、截止日期升序) allowed_categories = [p.test_category_id for p in permissions if p.test_category_id] query = select(TestWorkOrder).where( TestWorkOrder.test_status == 0, # 待测试 TestWorkOrder.tester_id.is_(None), # 未分配 TestWorkOrder.del_flag == '0' ) if allowed_categories: query = query.where(TestWorkOrder.test_category_id.in_(allowed_categories)) # 排序: 优先级高优先,截止日期近优先 query = query.order_by( desc(TestWorkOrder.priority), asc(TestWorkOrder.expected_finish_date) ) result = await db.execute(query.limit(1)) work_order = result.scalar_one_or_none() if not work_order: raise ServiceException(message='暂无可领取工单') # 4. 乐观锁领取 update_result = await db.execute( update(TestWorkOrder).where( TestWorkOrder.id == work_order.id, TestWorkOrder.tester_id.is_(None), # 确保未被他人领取 TestWorkOrder.del_flag == '0' ).values( tester_id=current_user_id, claimed_by=current_user_id, claimed_at=datetime.now(), test_status=1, # 测试中 update_by=str(current_user_id), update_time=datetime.now() ) ) if update_result.rowcount == 0: raise ServiceException(message='工单已被他人领取') await db.commit() return {'message': '领取成功', 'work_order_id': work_order.id} @classmethod async def get_pending_list(cls, db: AsyncSession, current_user_id: int, query_obj): """获取可领取工单列表""" # 获取用户权限 permissions = await TestPermissionDao.get_by_user_id(db, current_user_id) allowed_categories = [p.test_category_id for p in permissions if p.test_category_id] query = select(TestWorkOrder).where( TestWorkOrder.test_status == 0, TestWorkOrder.tester_id.is_(None), TestWorkOrder.del_flag == '0' ) if allowed_categories: query = query.where(TestWorkOrder.test_category_id.in_(allowed_categories)) # 排序 query = query.order_by( desc(TestWorkOrder.priority), asc(TestWorkOrder.expected_finish_date) ) # 分页 total_result = await db.execute(select(func.count()).select_from(query.subquery())) total = total_result.scalar() query = query.offset((query_obj.page_num - 1) * query_obj.page_size).limit(query_obj.page_size) result = await db.execute(query) rows = result.scalars().all() return { 'rows': [CamelCaseUtil.transform_result(row) for row in rows], 'total': total } @classmethod async def update_priority(cls, db: AsyncSession, work_order_id: int, priority: int, current_user_id: int): """管理人员调整工单优先级""" if priority < 1 or priority > 5: raise ServiceException(message='优先级必须在1-5之间') result = await db.execute( update(TestWorkOrder).where( TestWorkOrder.id == work_order_id, TestWorkOrder.del_flag == '0' ).values( priority=priority, update_by=str(current_user_id), update_time=datetime.now() ) ) if result.rowcount == 0: raise ServiceException(message='工单不存在') await db.commit() return {'message': '优先级调整成功'} @classmethod async def batch_claim_work_order(cls, db: AsyncSession, work_order_ids: List[int], current_user_id: int): """ 批量领取工单 逐个领取,记录成功和失败 """ success_count = 0 failed_count = 0 success_ids = [] failed_messages = [] for work_order_id in work_order_ids: try: result = await cls.claim_work_order(db, current_user_id) success_count += 1 success_ids.append(result['work_order_id']) except ServiceException as e: failed_count += 1 failed_messages.append(f'工单{work_order_id}: {e.message}') return { 'success_count': success_count, 'failed_count': failed_count, 'work_order_ids': success_ids, 'failed_messages': failed_messages } """管理人员修改预计完成日期""" result = await db.execute( update(TestWorkOrder).where( TestWorkOrder.id == work_order_id, TestWorkOrder.del_flag == '0' ).values( expected_finish_date=expected_date, update_by=str(current_user_id), update_time=datetime.now() ) ) if result.rowcount == 0: raise ServiceException(message='工单不存在') await db.commit() return {'message': '预计完成日期修改成功'}