inquiry.py 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. """询价单CRUD"""
  2. from typing import Optional, List
  3. from datetime import datetime
  4. from sqlalchemy.orm import Session
  5. from sqlalchemy import and_, func
  6. from app.models.models import BizInquiry, BizInquiryItem, BizInquiryItemHis, BizInquiryHis
  7. from app.crud.base import CRUDBase
  8. from app.core.utils import generate_id
  9. class InquiryCRUD(CRUDBase[BizInquiry]):
  10. """询价单CRUD操作"""
  11. def get_by_region(
  12. self,
  13. db: Session,
  14. region_id: str,
  15. status: str = None,
  16. skip: int = 0,
  17. limit: int = 20
  18. ) -> List[BizInquiry]:
  19. """根据区域获取询价单列表"""
  20. query = db.query(BizInquiry).filter(
  21. and_(
  22. BizInquiry.region_id == region_id,
  23. BizInquiry.is_del == 0
  24. )
  25. )
  26. if status:
  27. query = query.filter(BizInquiry.status == status)
  28. return query.order_by(BizInquiry.create_at.desc()).offset(skip).limit(limit).all()
  29. def get_published_by_region(
  30. self,
  31. db: Session,
  32. region_id: str,
  33. skip: int = 0,
  34. limit: int = 20
  35. ) -> List[BizInquiry]:
  36. """获取区域已发布的询价单列表"""
  37. return self.get_by_region(db, region_id, status="published", skip=skip, limit=limit)
  38. def get_multi_with_filters(
  39. self,
  40. db: Session,
  41. region_id: str = None,
  42. status: str = None,
  43. keyword: str = None,
  44. skip: int = 0,
  45. limit: int = 10
  46. ) -> tuple[List[BizInquiry], int]:
  47. """多条件查询询价单"""
  48. query = db.query(BizInquiry).filter(BizInquiry.is_del == 0)
  49. if region_id:
  50. query = query.filter(BizInquiry.region_id == region_id)
  51. if status:
  52. query = query.filter(BizInquiry.status == status)
  53. if keyword:
  54. query = query.filter(BizInquiry.title.like(f"%{keyword}%"))
  55. total = query.count()
  56. inquiries = query.order_by(BizInquiry.create_at.desc()).offset(skip).limit(limit).all()
  57. return inquiries, total
  58. def publish(self, db: Session, id: str) -> Optional[BizInquiry]:
  59. """发布询价单"""
  60. inquiry = self.get(db, id)
  61. if inquiry and inquiry.status == "draft":
  62. inquiry.status = "published"
  63. inquiry.publish_time = datetime.now()
  64. db.commit()
  65. db.refresh(inquiry)
  66. return inquiry
  67. def unpublish(self, db: Session, id: str) -> Optional[BizInquiry]:
  68. """取消发布询价单(published -> draft)"""
  69. inquiry = self.get(db, id)
  70. if inquiry and inquiry.status == "published":
  71. inquiry.status = "draft"
  72. # 保留 publish_time 作为历史痕迹;如需清空可在这里置 None
  73. db.commit()
  74. db.refresh(inquiry)
  75. return inquiry
  76. def get_current_published_by_region(self, db: Session, region_id: str) -> Optional[BizInquiry]:
  77. """获取区域当前发布中的询价单(最多1条,业务上应保证互斥)"""
  78. return db.query(BizInquiry).filter(
  79. and_(
  80. BizInquiry.region_id == region_id,
  81. BizInquiry.status == "published",
  82. BizInquiry.is_del == 0
  83. )
  84. ).order_by(BizInquiry.publish_time.desc(), BizInquiry.create_at.desc()).first()
  85. def close(self, db: Session, id: str) -> Optional[BizInquiry]:
  86. """关闭询价单"""
  87. inquiry = self.get(db, id)
  88. if inquiry and inquiry.status == "published":
  89. inquiry.status = "closed"
  90. inquiry.close_time = datetime.now()
  91. db.commit()
  92. db.refresh(inquiry)
  93. return inquiry
  94. def update_with_history(self, db: Session, id: str, obj_in: dict, updater: dict = None) -> Optional[BizInquiry]:
  95. """更新询价单并记录历史"""
  96. original = self.get(db, id)
  97. if not original:
  98. return None
  99. his_data = {
  100. "id": original.id,
  101. "region_id": original.region_id,
  102. "title": original.title,
  103. "status": original.status,
  104. "publish_time": original.publish_time,
  105. "close_time": original.close_time,
  106. "remark": original.remark,
  107. "create_at": original.create_at,
  108. "create_by": original.create_by,
  109. "create_name": original.create_name,
  110. "update_at": original.update_at,
  111. "update_by": original.update_by,
  112. }
  113. his = BizInquiryHis(**his_data)
  114. db.add(his)
  115. return self.update(db, id, obj_in, updater)
  116. def soft_delete_with_history(self, db: Session, id: str) -> bool:
  117. """删除询价单并记录历史"""
  118. original = self.get(db, id)
  119. if not original:
  120. return False
  121. his_data = {
  122. "id": original.id,
  123. "region_id": original.region_id,
  124. "title": original.title,
  125. "status": original.status,
  126. "publish_time": original.publish_time,
  127. "close_time": original.close_time,
  128. "remark": original.remark,
  129. "create_at": original.create_at,
  130. "create_by": original.create_by,
  131. "create_name": original.create_name,
  132. "update_at": original.update_at,
  133. "update_by": original.update_by,
  134. }
  135. his = BizInquiryHis(**his_data)
  136. db.add(his)
  137. return self.delete(db, id)
  138. class InquiryItemCRUD(CRUDBase[BizInquiryItem]):
  139. """询价单项CRUD操作"""
  140. def get_by_inquiry(self, db: Session, inquiry_id: str) -> List[BizInquiryItem]:
  141. """获取询价单的所有询价项"""
  142. return db.query(BizInquiryItem).filter(
  143. and_(
  144. BizInquiryItem.inquiry_id == inquiry_id,
  145. BizInquiryItem.is_del == 0
  146. )
  147. ).all()
  148. def get_multi_with_inquiry_ids(
  149. self,
  150. db: Session,
  151. inquiry_ids: List[str]
  152. ) -> List[BizInquiryItem]:
  153. """根据多个询价单ID获取询价项"""
  154. return db.query(BizInquiryItem).filter(
  155. and_(
  156. BizInquiryItem.inquiry_id.in_(inquiry_ids),
  157. BizInquiryItem.is_del == 0
  158. )
  159. ).all()
  160. def create_items(
  161. self,
  162. db: Session,
  163. inquiry_id: str,
  164. product_ids: List[str],
  165. creator: dict = None
  166. ) -> List[BizInquiryItem]:
  167. """批量创建询价项"""
  168. items = []
  169. for product_id in product_ids:
  170. item = BizInquiryItem(
  171. id=generate_id(),
  172. inquiry_id=inquiry_id,
  173. product_id=product_id,
  174. create_by=creator.get("user_id") if creator else None,
  175. create_name=creator.get("real_name") if creator else None
  176. )
  177. db.add(item)
  178. items.append(item)
  179. db.commit()
  180. for item in items:
  181. db.refresh(item)
  182. return items
  183. def update_items(
  184. self,
  185. db: Session,
  186. inquiry_id: str,
  187. product_ids: List[str],
  188. creator: dict = None
  189. ) -> List[BizInquiryItem]:
  190. """更新询价项(先删除旧的,再创建新的)"""
  191. existing_items = self.get_by_inquiry(db, inquiry_id)
  192. for item in existing_items:
  193. item.is_del = 1
  194. return self.create_items(db, inquiry_id, product_ids, creator)
  195. def delete_by_inquiry(self, db: Session, inquiry_id: str) -> bool:
  196. """删除询价单的所有询价项"""
  197. items = self.get_by_inquiry(db, inquiry_id)
  198. for item in items:
  199. item.is_del = 1
  200. db.commit()
  201. return True
  202. inquiry_crud = InquiryCRUD(BizInquiry)
  203. inquiry_item_crud = InquiryItemCRUD(BizInquiryItem)