Files
FastapiAdmin/backend/app/core/generic_service.py
T
zhangtao 53d2a9d13e chore: cleanup old frontend code and update project configs
This commit removes the deprecated frontend/web-old directory, updates various project configuration files including tsconfig, vite config, environment variables, and backend data models. It also fixes several API paths, adds tenant awareness to multiple models, and makes minor UI adjustments.
2026-05-27 01:12:03 +08:00

98 lines
2.8 KiB
Python

"""通用业务服务基类 — 减少 CRUD 样板代码。
使用方法:
class MyService(GenericService[MyModel, MyCreateSchema, MyUpdateSchema]):
model = MyModel
crud_class = MyCRUD
# 一行搞定分页查询
result = await MyService.page(auth, page_no=1, page_size=10)
"""
from __future__ import annotations
from typing import Any, Generic, TypeVar
from app.api.v1.module_system.auth.schema import AuthSchema
from app.core.base_crud import CRUDBase
from app.core.exceptions import CustomException
ModelT = TypeVar("ModelT")
CreateSchemaT = TypeVar("CreateSchemaT")
UpdateSchemaT = TypeVar("UpdateSchemaT")
class GenericService(Generic[ModelT, CreateSchemaT, UpdateSchemaT]):
"""通用 CRUD 服务基类。
子类须声明:
model: ModelT — SQLAlchemy 模型类
crud_class: type[CRUDBase] — 对应的 CRUD 类
"""
model: type[ModelT]
crud_class: type[CRUDBase[Any, Any, Any]]
# ── 分页查询 ──
@classmethod
async def page(
cls,
auth: AuthSchema,
*,
page_no: int = 1,
page_size: int = 10,
**filters: Any,
) -> dict:
crud = cls.crud_class(auth=auth)
return await crud.page(page_no=page_no, page_size=page_size, **filters)
# ── 详情查询 ──
@classmethod
async def detail(cls, auth: AuthSchema, id: int) -> dict:
crud = cls.crud_class(auth=auth)
obj = await crud.get_by_id(id)
if not obj:
raise CustomException(msg=f"{cls.model.__name__} 不存在", code=404)
return cls._to_dict(obj)
# ── 创建 ──
@classmethod
async def create(cls, auth: AuthSchema, data: CreateSchemaT) -> dict:
crud = cls.crud_class(auth=auth)
obj = await crud.create(data)
await auth.db.flush()
return cls._to_dict(obj)
# ── 更新 ──
@classmethod
async def update(cls, auth: AuthSchema, id: int, data: UpdateSchemaT) -> dict:
crud = cls.crud_class(auth=auth)
obj = await crud.get_by_id(id)
if not obj:
raise CustomException(msg=f"{cls.model.__name__} 不存在", code=404)
await crud.update(id, data)
await auth.db.flush()
return cls._to_dict(obj)
# ── 删除 ──
@classmethod
async def delete(cls, auth: AuthSchema, ids: list[int]) -> None:
crud = cls.crud_class(auth=auth)
await crud.delete(ids)
# ── 辅助 ──
@staticmethod
def _to_dict(obj: ModelT) -> dict:
"""将 ORM 对象转为字典。子类可重写以自定义序列化。"""
if hasattr(obj, "model_dump"):
return obj.model_dump()
if hasattr(obj, "__dict__"):
return {k: v for k, v in obj.__dict__.items() if not k.startswith("_")}
return {}