add backend source code
This commit is contained in:
149
backend/app/services/department_service.py
Normal file
149
backend/app/services/department_service.py
Normal file
@@ -0,0 +1,149 @@
|
||||
"""
|
||||
科室服务层
|
||||
"""
|
||||
from typing import Optional, List
|
||||
from sqlalchemy import select, func
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.orm import selectinload
|
||||
|
||||
from app.models.models import Department
|
||||
from app.schemas.schemas import DepartmentCreate, DepartmentUpdate, DepartmentTree
|
||||
|
||||
|
||||
class DepartmentService:
|
||||
"""科室服务"""
|
||||
|
||||
@staticmethod
|
||||
async def get_list(
|
||||
db: AsyncSession,
|
||||
dept_type: Optional[str] = None,
|
||||
is_active: Optional[bool] = None,
|
||||
page: int = 1,
|
||||
page_size: int = 20
|
||||
) -> tuple[List[Department], int]:
|
||||
"""获取科室列表"""
|
||||
query = select(Department)
|
||||
|
||||
if dept_type:
|
||||
query = query.where(Department.dept_type == dept_type)
|
||||
if is_active is not None:
|
||||
query = query.where(Department.is_active == is_active)
|
||||
|
||||
# 统计总数
|
||||
count_query = select(func.count()).select_from(query.subquery())
|
||||
total = await db.scalar(count_query)
|
||||
|
||||
# 分页
|
||||
query = query.order_by(Department.sort_order, Department.id)
|
||||
query = query.offset((page - 1) * page_size).limit(page_size)
|
||||
|
||||
result = await db.execute(query)
|
||||
departments = result.scalars().all()
|
||||
|
||||
return departments, total or 0
|
||||
|
||||
@staticmethod
|
||||
async def get_by_id(db: AsyncSession, dept_id: int) -> Optional[Department]:
|
||||
"""根据ID获取科室"""
|
||||
result = await db.execute(
|
||||
select(Department).where(Department.id == dept_id)
|
||||
)
|
||||
return result.scalar_one_or_none()
|
||||
|
||||
@staticmethod
|
||||
async def get_by_code(db: AsyncSession, code: str) -> Optional[Department]:
|
||||
"""根据编码获取科室"""
|
||||
result = await db.execute(
|
||||
select(Department).where(Department.code == code)
|
||||
)
|
||||
return result.scalar_one_or_none()
|
||||
|
||||
@staticmethod
|
||||
async def create(db: AsyncSession, dept_data: DepartmentCreate) -> Department:
|
||||
"""创建科室"""
|
||||
# 计算层级
|
||||
level = 1
|
||||
if dept_data.parent_id:
|
||||
parent = await DepartmentService.get_by_id(db, dept_data.parent_id)
|
||||
if parent:
|
||||
level = parent.level + 1
|
||||
|
||||
department = Department(
|
||||
**dept_data.model_dump(exclude={'level'}),
|
||||
level=level
|
||||
)
|
||||
db.add(department)
|
||||
await db.flush()
|
||||
await db.refresh(department)
|
||||
return department
|
||||
|
||||
@staticmethod
|
||||
async def update(db: AsyncSession, dept_id: int, dept_data: DepartmentUpdate) -> Optional[Department]:
|
||||
"""更新科室"""
|
||||
department = await DepartmentService.get_by_id(db, dept_id)
|
||||
if not department:
|
||||
return None
|
||||
|
||||
update_data = dept_data.model_dump(exclude_unset=True)
|
||||
for key, value in update_data.items():
|
||||
setattr(department, key, value)
|
||||
|
||||
await db.flush()
|
||||
await db.refresh(department)
|
||||
return department
|
||||
|
||||
@staticmethod
|
||||
async def delete(db: AsyncSession, dept_id: int) -> bool:
|
||||
"""删除科室"""
|
||||
department = await DepartmentService.get_by_id(db, dept_id)
|
||||
if not department:
|
||||
return False
|
||||
|
||||
# 检查是否有子科室
|
||||
result = await db.execute(
|
||||
select(func.count()).where(Department.parent_id == dept_id)
|
||||
)
|
||||
if result.scalar() > 0:
|
||||
return False
|
||||
|
||||
await db.delete(department)
|
||||
return True
|
||||
|
||||
@staticmethod
|
||||
async def get_tree(db: AsyncSession, dept_type: Optional[str] = None) -> List[DepartmentTree]:
|
||||
"""获取科室树形结构"""
|
||||
query = select(Department).order_by(Department.sort_order, Department.id)
|
||||
|
||||
if dept_type:
|
||||
query = query.where(Department.dept_type == dept_type)
|
||||
|
||||
result = await db.execute(query)
|
||||
departments = result.scalars().all()
|
||||
|
||||
# 构建树形结构 - 手动构建避免懒加载问题
|
||||
dept_map = {}
|
||||
for d in departments:
|
||||
dept_map[d.id] = DepartmentTree(
|
||||
id=d.id,
|
||||
name=d.name,
|
||||
code=d.code,
|
||||
dept_type=d.dept_type,
|
||||
parent_id=d.parent_id,
|
||||
level=d.level,
|
||||
sort_order=d.sort_order,
|
||||
is_active=d.is_active,
|
||||
description=d.description,
|
||||
created_at=d.created_at,
|
||||
updated_at=d.updated_at,
|
||||
children=[]
|
||||
)
|
||||
roots = []
|
||||
|
||||
for dept in departments:
|
||||
tree_node = dept_map[dept.id]
|
||||
if dept.parent_id and dept.parent_id in dept_map:
|
||||
dept_map[dept.parent_id].children.append(tree_node)
|
||||
else:
|
||||
roots.append(tree_node)
|
||||
|
||||
return roots
|
||||
Reference in New Issue
Block a user