from datetime import datetime from typing import Optional from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select, func from loguru import logger from app.models.material import Coil, MaterialTracking, CoilStatus from app.services.message_parser import dispatcher class MaterialService: @staticmethod async def get_coil(db: AsyncSession, coil_no: str) -> Optional[Coil]: result = await db.execute(select(Coil).where(Coil.coil_no == coil_no)) return result.scalar_one_or_none() @staticmethod async def create_tracking(db: AsyncSession, coil: Coil, event_type: str, position: str = None, **kwargs) -> MaterialTracking: tracking = MaterialTracking( coil_id=coil.id, coil_no=coil.coil_no, position=position, event_type=event_type, event_time=kwargs.get("event_time", datetime.now()), **{k: v for k, v in kwargs.items() if k != "event_time"}, ) db.add(tracking) await db.flush() return tracking @staticmethod async def update_coil_status(db: AsyncSession, coil: Coil, status: CoilStatus): coil.status = status await db.flush() material_service = MaterialService() # 注册L1报文处理器 @dispatcher.register("PC01") async def handle_coil_entry(data: dict): """处理卷材入口报文""" from app.database import AsyncSessionLocal async with AsyncSessionLocal() as db: coil = await material_service.get_coil(db, data["coil_no"]) if coil: await material_service.update_coil_status(db, coil, CoilStatus.ON_LINE) await material_service.create_tracking( db, coil, "entry", position="入口", **data ) await db.commit() logger.info(f"卷材入线: {data['coil_no']}") @dispatcher.register("PC02") async def handle_coil_exit(data: dict): """处理卷材出口报文""" from app.database import AsyncSessionLocal async with AsyncSessionLocal() as db: coil = await material_service.get_coil(db, data["coil_no"]) if coil: await material_service.update_coil_status(db, coil, CoilStatus.FINISHED) await material_service.create_tracking( db, coil, "exit", position="出口", **data ) await db.commit() logger.info(f"卷材出线: {data['coil_no']}")