Files
xiaoxia-saas/packages/adapters/sqlalchemy_impl/points_order_repository.py
T

83 lines
2.5 KiB
Python

from __future__ import annotations
from datetime import datetime, timezone
from uuid import uuid4
from sqlalchemy.orm import Session
from packages.adapters.sqlalchemy_impl.models import PointsOrderModel
class SQLAlchemyPointsOrderRepository:
"""积分充值订单仓储."""
def __init__(self, session: Session):
self.session = session
def create(
self,
*,
user_id: str,
package_name: str,
points_amount: int,
price_cents: int,
original_price_cents: int,
discount: float = 1.0,
currency: str = "CNY",
payment_method: str | None = None,
expire_at: datetime | None = None,
) -> PointsOrderModel:
model = PointsOrderModel(
id=str(uuid4()),
user_id=user_id,
package_name=package_name,
points_amount=points_amount,
price_cents=price_cents,
currency=currency,
discount=discount,
original_price_cents=original_price_cents,
status="pending",
payment_method=payment_method,
expire_at=expire_at,
created_at=datetime.now(timezone.utc),
)
self.session.add(model)
self.session.flush()
return model
def get_by_id(self, order_id: str) -> PointsOrderModel | None:
return self.session.get(PointsOrderModel, order_id)
def update_status(
self,
order_id: str,
*,
status: str,
payment_id: str | None = None,
paid_at: datetime | None = None,
) -> PointsOrderModel | None:
model = self.session.get(PointsOrderModel, order_id)
if model is None:
return None
model.status = status
if payment_id is not None:
model.payment_id = payment_id
if paid_at is not None:
model.paid_at = paid_at
self.session.flush()
return model
def list_expired_pending(self, before: datetime | None = None) -> list[PointsOrderModel]:
"""查出 expire_at 已过仍处于 pending 状态的订单(可用于定时取消)."""
if before is None:
before = datetime.now(timezone.utc)
return (
self.session.query(PointsOrderModel)
.filter(
PointsOrderModel.status == "pending",
PointsOrderModel.expire_at.isnot(None),
PointsOrderModel.expire_at < before,
)
.all()
)