59 lines
2.6 KiB
Python
59 lines
2.6 KiB
Python
from sqlalchemy import exists, select
|
|
from sqlalchemy.orm import Session, selectinload
|
|
|
|
from app.models.source_case import CaseBase, CaseExamItem, TeachingCase, TraditionalCase
|
|
|
|
|
|
class CaseRepository:
|
|
"""病例只读仓储:读取已发布病例、模式扩展数据和固定检查项目。"""
|
|
|
|
def __init__(self, db: Session) -> None:
|
|
self.db = db
|
|
|
|
def list_active_cases(
|
|
self,
|
|
department_id: int | None = None,
|
|
training_type: str | None = None,
|
|
mode: str | None = None,
|
|
) -> list[CaseBase]:
|
|
"""病例列表:从 case_base 读取已发布病例,并按模式匹配扩展表。"""
|
|
normalized_mode = "practice" if mode == "novice" else mode
|
|
stmt = (
|
|
select(CaseBase)
|
|
.options(selectinload(CaseBase.traditional_case), selectinload(CaseBase.teaching_case))
|
|
.where(CaseBase.status == 1, CaseBase.publish_status == 1)
|
|
)
|
|
if department_id:
|
|
stmt = stmt.where(CaseBase.department_id == department_id)
|
|
if training_type:
|
|
stmt = stmt.where(CaseBase.case_type == training_type)
|
|
if normalized_mode == "practice":
|
|
stmt = stmt.where(exists().where(TraditionalCase.case_id == CaseBase.id))
|
|
if normalized_mode == "teaching":
|
|
stmt = stmt.where(exists().where(TeachingCase.case_id == CaseBase.id))
|
|
return list(self.db.scalars(stmt.order_by(CaseBase.id.desc())).all())
|
|
|
|
def get_active_case(self, case_id: int) -> CaseBase | None:
|
|
"""病例详情:读取病例主表及训练所需的扩展表、评分规则和检查项目。"""
|
|
stmt = (
|
|
select(CaseBase)
|
|
.options(
|
|
selectinload(CaseBase.traditional_case),
|
|
selectinload(CaseBase.teaching_case),
|
|
selectinload(CaseBase.scoring_rules),
|
|
selectinload(CaseBase.exam_items),
|
|
)
|
|
.where(CaseBase.id == case_id, CaseBase.status == 1, CaseBase.publish_status == 1)
|
|
)
|
|
return self.db.scalar(stmt)
|
|
|
|
def get_exam_items(self, case_id: int) -> list[CaseExamItem]:
|
|
"""检查项目:读取当前病例下全部可申请检查检验项目。"""
|
|
stmt = select(CaseExamItem).where(CaseExamItem.case_id == case_id).order_by(CaseExamItem.display_order)
|
|
return list(self.db.scalars(stmt).all())
|
|
|
|
def get_exam_item(self, case_id: int, item_code: str) -> CaseExamItem | None:
|
|
"""检查结果:按病例和项目编码读取数据库中的固定结果。"""
|
|
stmt = select(CaseExamItem).where(CaseExamItem.case_id == case_id, CaseExamItem.item_code == item_code)
|
|
return self.db.scalar(stmt)
|