product.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. """商品CRUD"""
  2. from typing import Optional, List
  3. from sqlalchemy.orm import Session, defer
  4. from sqlalchemy import and_, func, or_
  5. from app.models.models import BasProduct, BasProductHis
  6. from app.crud.base import CRUDBase
  7. class ProductCRUD(CRUDBase[BasProduct]):
  8. """商品CRUD操作"""
  9. def get_by_name(self, db: Session, name: str) -> Optional[BasProduct]:
  10. """根据名称获取商品"""
  11. return db.query(BasProduct).filter(
  12. and_(BasProduct.name == name, BasProduct.is_del == 0)
  13. ).first()
  14. def get_active_all(self, db: Session) -> List[BasProduct]:
  15. """获取所有启用的商品"""
  16. return db.query(BasProduct).filter(
  17. and_(BasProduct.is_del == 0, BasProduct.is_active == True)
  18. ).order_by(BasProduct.create_at.desc()).all()
  19. def get_multi_by_category(self, db: Session, category_id: str) -> List[BasProduct]:
  20. """根据分类获取商品"""
  21. return db.query(BasProduct).filter(
  22. and_(BasProduct.category_id == category_id, BasProduct.is_del == 0, BasProduct.is_active == True)
  23. ).order_by(BasProduct.create_at.desc()).all()
  24. def get_multi_with_filters(
  25. self,
  26. db: Session,
  27. category_id: str = None,
  28. keyword: str = None,
  29. is_active: bool = None,
  30. skip: int = 0,
  31. limit: int = 10,
  32. *,
  33. defer_detail_content: bool = False,
  34. ) -> tuple[List[BasProduct], int]:
  35. """多条件查询商品"""
  36. filters = [BasProduct.is_del == 0]
  37. if category_id:
  38. filters.append(BasProduct.category_id == category_id)
  39. if is_active is not None:
  40. filters.append(BasProduct.is_active == is_active)
  41. if keyword:
  42. filters.append(
  43. or_(
  44. BasProduct.name.like(f"%{keyword}%"),
  45. BasProduct.description.like(f"%{keyword}%"),
  46. )
  47. )
  48. total = (
  49. db.query(func.count(BasProduct.id))
  50. .filter(*filters)
  51. .order_by(None)
  52. .scalar()
  53. or 0
  54. )
  55. query = db.query(BasProduct).filter(*filters)
  56. if defer_detail_content:
  57. query = query.options(defer(BasProduct.detail_content))
  58. products = query.order_by(BasProduct.create_at.desc()).offset(skip).limit(limit).all()
  59. return products, total
  60. def update_with_history(self, db: Session, id: str, obj_in: dict, updater: dict = None) -> Optional[BasProduct]:
  61. """更新商品并记录历史"""
  62. original = self.get(db, id)
  63. if not original:
  64. return None
  65. his_data = {
  66. "id": original.id,
  67. "name": original.name,
  68. "category_id": original.category_id,
  69. "unit_id": original.unit_id,
  70. "measure_value": getattr(original, "measure_value", None),
  71. "description": original.description,
  72. "image_url": original.image_url,
  73. "is_active": original.is_active,
  74. "create_at": original.create_at,
  75. "create_by": original.create_by,
  76. "create_name": original.create_name,
  77. "update_at": original.update_at,
  78. "update_by": original.update_by,
  79. }
  80. his = BasProductHis(**his_data)
  81. db.add(his)
  82. return self.update(db, id, obj_in, updater)
  83. def soft_delete_with_history(self, db: Session, id: str) -> bool:
  84. """删除商品并记录历史"""
  85. original = self.get(db, id)
  86. if not original:
  87. return False
  88. his_data = {
  89. "id": original.id,
  90. "name": original.name,
  91. "category_id": original.category_id,
  92. "unit_id": original.unit_id,
  93. "measure_value": getattr(original, "measure_value", None),
  94. "description": original.description,
  95. "image_url": original.image_url,
  96. "is_active": original.is_active,
  97. "create_at": original.create_at,
  98. "create_by": original.create_by,
  99. "create_name": original.create_name,
  100. "update_at": original.update_at,
  101. "update_by": original.update_by,
  102. }
  103. his = BasProductHis(**his_data)
  104. db.add(his)
  105. return self.delete(db, id)
  106. product_crud = ProductCRUD(BasProduct)