"""实验室样本处理数据台账 API""" from typing import Any, Dict, Optional from fastapi import APIRouter, Depends, Query from pydantic import BaseModel, ConfigDict, Field from sqlalchemy.orm import Session from app.core.database import get_db from app.core.menu_guard import require_menu_code from app.core.response import error_response, success_response from app.crud import lab_sample_process as svc from app.models.models import SysUser from app.services import lab_sample_process as ledger router = APIRouter(prefix="/web/admin", tags=["质检管理"]) LIST_MENU = "biz:labSampleProcess:list" SUPPLEMENT_MENU = "biz:labSampleProcess:supplement" def _tenant_no(db: Session, user: dict) -> str: user_id = user.get("user_id") if not user_id: raise PermissionError("用户身份信息缺失,无法确定租户") sys_user = db.query(SysUser).filter(SysUser.id == user_id).first() if not sys_user or not sys_user.tenant_no: raise PermissionError("用户租户信息缺失") return sys_user.tenant_no def _user_id(user: dict) -> str: uid = user.get("user_id") if not uid: raise PermissionError("用户身份信息缺失") return str(uid) def _dept_id(user: dict) -> str: return str(user.get("dept_id") or user.get("create_dept_id") or "") class SupplementBody(BaseModel): model_config = ConfigDict(populate_by_name=True) lab_storage_code: str = Field(..., alias="labStorageCode") reception_source: str = Field(..., alias="receptionSource") sample_type_name: str = Field(..., alias="sampleTypeName") payload: Dict[str, Any] = Field(default_factory=dict) remark: Optional[str] = None @router.get("/lab-sample-process/list") def list_lab_sample_process( tabKey: str = Query(..., description="cell_hsc|donation_hsc|cell_msc|donation_msc"), page: int = Query(1, ge=1), pageSize: int = Query(10, ge=1, le=200), labStorageCode: Optional[str] = Query(None), motherName: Optional[str] = Query(None), createTimeStart: Optional[str] = Query(None), createTimeEnd: Optional[str] = Query(None), db: Session = Depends(get_db), user=Depends(require_menu_code(LIST_MENU)), ): try: tenant_no = _tenant_no(db, user) items, total = svc.list_ledger( db, tab_key=tabKey, page=page, page_size=pageSize, tenant_no=tenant_no, lab_storage_code=labStorageCode, mother_name=motherName, create_time_start=createTimeStart, create_time_end=createTimeEnd, user_info=user, ) return success_response( data={ "list": items, "total": total, "page": page, "pageSize": pageSize, "tabKey": tabKey, "tabMeta": ledger.TAB_META.get(tabKey), "supplementKeys": ledger.SUPPLEMENT_KEYS.get(tabKey, []), } ) except PermissionError as e: return error_response(str(e), code=403) except ValueError as e: return error_response(str(e)) except Exception as e: return error_response(f"查询失败:{e}") @router.get("/lab-sample-process/supplement") def get_supplement( labStorageCode: str = Query(...), db: Session = Depends(get_db), user=Depends(require_menu_code(LIST_MENU)), ): try: tenant_no = _tenant_no(db, user) data = svc.get_supplement(db, tenant_no=tenant_no, lab_storage_code=labStorageCode) return success_response(data=data or {"labStorageCode": labStorageCode, "payload": {}}) except PermissionError as e: return error_response(str(e), code=403) except Exception as e: return error_response(f"查询补录失败:{e}") @router.put("/lab-sample-process/supplement") def save_supplement( body: SupplementBody, db: Session = Depends(get_db), user=Depends(require_menu_code(SUPPLEMENT_MENU)), ): try: tenant_no = _tenant_no(db, user) data = svc.upsert_supplement( db, tenant_no=tenant_no, user_id=_user_id(user), dept_id=_dept_id(user), lab_storage_code=body.lab_storage_code, reception_source=body.reception_source, sample_type_name=body.sample_type_name, payload=body.payload or {}, remark=body.remark, ) return success_response(data=data, message="补录已保存") except PermissionError as e: return error_response(str(e), code=403) except ValueError as e: return error_response(str(e)) except Exception as e: return error_response(f"保存补录失败:{e}")