| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166 |
- """CRUD基础类"""
- from typing import TypeVar, Generic, Type, Optional, List, Any
- from sqlalchemy.orm import Session
- from sqlalchemy import and_, or_
- import re
- from app.core.utils import generate_id
- from app.core.database import Base
- from sqlalchemy import func
- ModelType = TypeVar("ModelType", bound=Base)
- def camel_to_snake(name: str) -> str:
- """驼峰命名转蛇形命名"""
- s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name)
- return re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1).lower()
- def get_model_attr(obj, key: str):
- """获取模型的属性名,支持驼峰转蛇形"""
- # 先尝试直接匹配
- if hasattr(obj, key):
- return key
- # 尝试驼峰转蛇形
- snake_key = camel_to_snake(key)
- if hasattr(obj, snake_key):
- return snake_key
- # 如果都没有,返回None
- return None
- class CRUDBase(Generic[ModelType]):
- """CRUD基类"""
- def __init__(self, model: Type[ModelType]):
- self.model = model
- def get(self, db: Session, id: str) -> Optional[ModelType]:
- """根据ID获取单条记录"""
- return db.query(self.model).filter(self.model.id == id).first()
- def get_multi(
- self,
- db: Session,
- skip: int = 0,
- limit: int = 100,
- filters: List[Any] = None,
- order_by: str = None,
- order_type: str = "desc"
- ) -> List[ModelType]:
- """获取多条记录"""
- query = db.query(self.model)
- if filters:
- query = query.filter(*filters)
- if order_by:
- order_column = getattr(self.model, order_by, None)
- if order_column:
- if order_type == "asc":
- query = query.order_by(order_column.asc())
- else:
- query = query.order_by(order_column.desc())
- else:
- query = query.order_by(self.model.create_at.desc())
- return query.offset(skip).limit(limit).all()
- def get_all(self, db: Session, filters: List[Any] = None) -> List[ModelType]:
- """获取所有记录"""
- query = db.query(self.model)
- if filters:
- query = query.filter(*filters)
- return query.all()
- def create(self, db: Session, obj_in: dict, creator: dict = None) -> ModelType:
- """创建记录"""
- obj = self.model()
- for key, value in obj_in.items():
- attr_name = get_model_attr(obj, key)
- if attr_name:
- setattr(obj, attr_name, value)
- # 设置ID
- if not obj.id:
- obj.id = generate_id()
- # 设置创建人信息
- if creator:
- if not obj.create_by and "user_id" in creator:
- obj.create_by = creator["user_id"]
- if not obj.create_name and "real_name" in creator:
- obj.create_name = creator["real_name"]
- db.add(obj)
- db.commit()
- db.refresh(obj)
- return obj
- def update(self, db: Session, id: str, obj_in: dict, updater: dict = None) -> Optional[ModelType]:
- """更新记录"""
- obj = self.get(db, id)
- if obj:
- for key, value in obj_in.items():
- attr_name = get_model_attr(obj, key)
- if attr_name and key not in ["id", "create_at", "create_by", "create_name"]:
- setattr(obj, attr_name, value)
- # 设置更新人信息
- if updater:
- if "user_id" in updater:
- obj.update_by = updater["user_id"]
- if "real_name" in updater:
- obj.update_name = updater.get("real_name", obj.create_name)
- obj.update_at = func.now()
- db.commit()
- db.refresh(obj)
- return obj
- def delete(self, db: Session, id: str) -> bool:
- """删除记录(软删除)"""
- obj = self.get(db, id)
- if obj:
- if hasattr(obj, "is_del"):
- obj.is_del = 1
- else:
- db.delete(obj)
- db.commit()
- return True
- return False
- def hard_delete(self, db: Session, id: str) -> bool:
- """物理删除"""
- obj = self.get(db, id)
- if obj:
- db.delete(obj)
- db.commit()
- return True
- return False
- def count(self, db: Session, filters: List[Any] = None) -> int:
- """统计数量"""
- query = db.query(self.model)
- if filters:
- query = query.filter(*filters)
- return query.count()
- def exists(self, db: Session, filters: List[Any] = None) -> bool:
- """检查记录是否存在"""
- query = db.query(self.model)
- if filters:
- query = query.filter(*filters)
- return query.first() is not None
- class HistoryCRUD(CRUDBase[ModelType]):
- """历史表CRUD类"""
- def create_history(self, db: Session, original_data: dict) -> ModelType:
- """创建历史记录"""
- obj = self.model()
- # 复制原始数据到历史表
- for key, value in original_data.items():
- if hasattr(obj, key):
- setattr(obj, key, value)
- # 设置历史记录创建时间
- if hasattr(obj, "his_create_at"):
- obj.his_create_at = func.now()
- db.add(obj)
- db.commit()
- db.refresh(obj)
- return obj
|