"""超期预警 模块服务层 —— 只读查询 + 标记处理;写入由每日扫描 job 直接落库。""" from typing import Any from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from app.core.base_schema import AuthSchema, PageResultSchema from app.core.exceptions import CustomException from .crud import BreedingAlertCRUD from .model import AlertModel from .schema import AlertOutSchema, AlertQueryParam class AlertService: """预警中心 —— 查询 + 处理。生成侧在 job.py,直接 db.add(不经 CRUDBase,防自审计递归)。""" def __init__(self, auth: AuthSchema, db: AsyncSession) -> None: self.auth = auth self.db = db async def page( self, page_no: int, page_size: int, search: AlertQueryParam | None = None, order_by: list[dict[str, str]] | None = None, ) -> PageResultSchema[AlertOutSchema]: from app.utils.common_util import search_to_dict return await BreedingAlertCRUD(self.auth, self.db).page( offset=(page_no - 1) * page_size, limit=page_size, order_by=order_by or [{"id": "desc"}], search=search_to_dict(search, {}), out_schema=AlertOutSchema, ) async def get_list(self, search: AlertQueryParam | None = None) -> list[AlertOutSchema]: from app.utils.common_util import search_to_dict objs = await BreedingAlertCRUD(self.auth, self.db).get_list( search=search_to_dict(search, {}), order_by=[{"id": "desc"}] ) return [AlertOutSchema.model_validate(o) for o in objs] async def detail(self, id: int) -> AlertOutSchema: obj = await BreedingAlertCRUD(self.auth, self.db).get(id=id) if not obj: raise CustomException(msg="该预警不存在") return AlertOutSchema.model_validate(obj) async def resolve(self, id: int) -> AlertOutSchema: obj = await BreedingAlertCRUD(self.auth, self.db).get(id=id) if not obj: raise CustomException(msg="该预警不存在") obj.status = "resolved" obj.updated_id = self.auth.user.id if self.auth.user.id else None self.db.add(obj) await self.db.flush() return AlertOutSchema.model_validate(obj) async def options(self) -> dict[str, Any]: """前端筛选下拉:预警类型 / 实体类型 去重集合。""" alert_types = (await self.db.execute( select(AlertModel.alert_type).distinct() )).scalars().all() entity_types = (await self.db.execute( select(AlertModel.entity_type).distinct() )).scalars().all() return {"alert_types": sorted(alert_types), "entity_types": sorted(entity_types)}