Files
danial 949a0d4e61 feat(apple): 重构并实现Apple iTunes和June客户端API模块
- 重命名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客户端类
2025-11-01 15:22:21 +08:00

94 lines
2.9 KiB
Python

"""
App B Router - API endpoints for product management.
"""
from fastapi import APIRouter, Depends
from sqlalchemy.ext.asyncio import AsyncSession
from core.database import get_session
from core.responses import ApiResponse, success, paginated, ERROR_RESPONSES
from core.dependencies import get_trace_id
from apps.apple.schemas import ProductCreate, ProductResponse
from apps.apple.services import ProductService
router = APIRouter(
prefix="/app-b",
tags=["App B - Products"]
)
@router.post(
"/products",
response_model=ApiResponse[ProductResponse],
status_code=201,
summary="Create a new product",
description="Create a new product with SKU, name, price, and stock",
responses={
201: {"description": "Product created successfully"},
400: ERROR_RESPONSES[400],
409: ERROR_RESPONSES[409],
422: ERROR_RESPONSES[422],
500: ERROR_RESPONSES[500],
}
)
async def create_product(
product_data: ProductCreate,
session: AsyncSession = Depends(get_session),
trace_id: str = Depends(get_trace_id)
) -> ApiResponse[ProductResponse]:
"""Create a new product."""
product = await ProductService.create_product(session, product_data)
product_response = ProductResponse.model_validate(product)
return success(data=product_response, message="Product created successfully", trace_id=trace_id)
@router.get(
"/products/{product_id}",
response_model=ApiResponse[ProductResponse],
summary="Get product by ID",
description="Retrieve a product by its ID",
responses={
200: {"description": "Product retrieved successfully"},
404: ERROR_RESPONSES[404],
500: ERROR_RESPONSES[500],
}
)
async def get_product(
product_id: int,
session: AsyncSession = Depends(get_session),
trace_id: str = Depends(get_trace_id)
) -> ApiResponse[ProductResponse]:
"""Get product by ID."""
product = await ProductService.get_product(session, product_id)
product_response = ProductResponse.model_validate(product)
return success(data=product_response, trace_id=trace_id)
@router.get(
"/products",
response_model=ApiResponse,
summary="List all products",
description="List all products with pagination support",
responses={
200: {"description": "Products retrieved successfully"},
400: ERROR_RESPONSES[400],
500: ERROR_RESPONSES[500],
}
)
async def list_products(
page: int = 1,
page_size: int = 10,
session: AsyncSession = Depends(get_session),
trace_id: str = Depends(get_trace_id)
) -> ApiResponse:
"""List all products with pagination."""
skip = (page - 1) * page_size
products, total = await ProductService.list_products(session, skip, page_size)
product_responses = [ProductResponse.model_validate(product) for product in products]
return paginated(
items=product_responses,
total=total,
page=page,
page_size=page_size,
trace_id=trace_id
)