"""报销模块 Service 基类 — 租户隔离 + UUID + 软删除。""" from __future__ import annotations from typing import Any, List, Optional, Sequence, Tuple, Type, TypeVar from sqlalchemy.orm import Session from app.core.utils import generate_uuid M = TypeVar("M") class BxCrudService: @staticmethod def get_by_id(model: Type[M], db: Session, id: str, tenant_no: str) -> Optional[M]: query = db.query(model).filter(model.id == id, model.tenant_no == tenant_no) if hasattr(model, "del_flag"): query = query.filter(model.del_flag == 0) return query.first() @staticmethod def get_paged( model: Type[M], db: Session, tenant_no: str, page: int, page_size: int, filters: Optional[List[Any]] = None, ) -> Tuple[Sequence[M], int]: query = db.query(model).filter(model.tenant_no == tenant_no) if hasattr(model, "del_flag"): query = query.filter(model.del_flag == 0) if filters: query = query.filter(*filters) total = query.count() if hasattr(model, "sort_order"): query = query.order_by(model.sort_order.asc(), model.create_time.desc()) else: query = query.order_by(model.create_time.desc()) rows = query.offset((page - 1) * page_size).limit(page_size).all() return rows, total @staticmethod def create( model: Type[M], db: Session, obj_in: dict, *, tenant_no: str, user_id: str, dept_id: str, ) -> M: data = dict(obj_in) data.setdefault("id", generate_uuid()) data["tenant_no"] = tenant_no data["create_by"] = user_id data["create_dept_id"] = dept_id or "" obj = model(**data) db.add(obj) db.flush() return obj @staticmethod def update( model: Type[M], db: Session, id: str, tenant_no: str, obj_in: dict, *, user_id: str, ) -> Optional[M]: obj = BxCrudService.get_by_id(model, db, id, tenant_no) if not obj: return None for key, value in obj_in.items(): setattr(obj, key, value) if hasattr(obj, "update_by"): obj.update_by = user_id db.flush() return obj @staticmethod def soft_delete(model: Type[M], db: Session, id: str, tenant_no: str, *, user_id: str = "") -> bool: obj = BxCrudService.get_by_id(model, db, id, tenant_no) if not obj: return False obj.del_flag = 1 if hasattr(obj, "update_by") and user_id: obj.update_by = user_id db.flush() return True