- 重命名apps/app_b为apps/apple,调整项目结构 - 新增apps.apple.clients.itunes模块,实现iTunes API客户端功能 - 实现iTunes登录、兑换和查询接口,支持错误重试和状态处理 - 设计解析Apple XML响应的工具函数,提升数据处理能力 - 定义iTunes登录和兑换相关数据模型,基于Pydantic提升数据校验 - 新增apps.apple.clients.june模块,实现June API客户端功能 - 实现六月客户端登录、状态检测、签名获取及远程账户登录 - 设计June客户端请求加密与签名机制,保障接口安全通信 - 增加六月客户端配置、加密工具和辅助函数支持 - 完善模块__init__.py文件,明确导出API客户端类
79 lines
2.2 KiB
Python
79 lines
2.2 KiB
Python
"""
|
|
App B Services - Business logic for products.
|
|
"""
|
|
|
|
from datetime import datetime
|
|
from sqlalchemy import select
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
from apps.apple.models import Product
|
|
from apps.apple.schemas import ProductCreate, ProductUpdate
|
|
from core.exceptions import NotFoundException, AlreadyExistsException
|
|
|
|
|
|
class ProductService:
|
|
"""Service for product business logic."""
|
|
|
|
@staticmethod
|
|
async def create_product(
|
|
session: AsyncSession,
|
|
product_data: ProductCreate
|
|
) -> Product:
|
|
"""Create a new product."""
|
|
# Check if SKU exists
|
|
result = await session.execute(
|
|
select(Product).where(Product.sku == product_data.sku)
|
|
)
|
|
if result.scalar_one_or_none():
|
|
raise AlreadyExistsException(
|
|
message=f"Product with SKU '{product_data.sku}' already exists",
|
|
resource="Product"
|
|
)
|
|
|
|
product = Product(
|
|
**product_data.model_dump(),
|
|
created_at=datetime.utcnow(),
|
|
updated_at=datetime.utcnow()
|
|
)
|
|
|
|
session.add(product)
|
|
await session.commit()
|
|
await session.refresh(product)
|
|
|
|
return product
|
|
|
|
@staticmethod
|
|
async def get_product(
|
|
session: AsyncSession,
|
|
product_id: int
|
|
) -> Product:
|
|
"""Get product by ID."""
|
|
result = await session.execute(
|
|
select(Product).where(Product.id == product_id)
|
|
)
|
|
product = result.scalar_one_or_none()
|
|
|
|
if not product:
|
|
raise NotFoundException(
|
|
message=f"Product with ID {product_id} not found",
|
|
resource="Product"
|
|
)
|
|
|
|
return product
|
|
|
|
@staticmethod
|
|
async def list_products(
|
|
session: AsyncSession,
|
|
skip: int = 0,
|
|
limit: int = 100
|
|
) -> tuple[list[Product], int]:
|
|
"""List all products with pagination."""
|
|
count_result = await session.execute(select(Product))
|
|
total = len(count_result.all())
|
|
|
|
result = await session.execute(
|
|
select(Product).offset(skip).limit(limit)
|
|
)
|
|
products = result.scalars().all()
|
|
|
|
return list(products), total
|