CoolBotDataSys/api/routes/collections.py

157 lines
5.8 KiB
Python

"""藏品路由"""
from fastapi import APIRouter, HTTPException, Query
from typing import Optional, List
from datetime import datetime
from api.models.request import CollectionCreate, CollectionUpdate
from api.models.response import CollectionResponse
from api.middleware.response import ApiResponse, PaginatedData
from database import db
router = APIRouter(prefix="/api/v1/collections", tags=["collections"])
@router.get("", response_model=ApiResponse)
async def list_collections(
category: Optional[str] = Query(None, description="品类筛选"),
rarity: Optional[str] = Query(None, description="珍惜度筛选"),
status: Optional[str] = Query(None, description="状态筛选"),
page: int = Query(1, ge=1, description="页码"),
page_size: int = Query(20, ge=1, le=100, description="每页数量")
):
"""获取藏品列表(分页)"""
offset = (page - 1) * page_size
where_clauses = []
params = []
if category:
where_clauses.append("category = %s")
params.append(category)
if rarity:
where_clauses.append("rarity = %s")
params.append(rarity)
if status:
where_clauses.append("status = %s")
params.append(status)
where_sql = " WHERE " + " AND ".join(where_clauses) if where_clauses else ""
with db.get_cursor() as cursor:
cursor.execute(f"SELECT COUNT(*) as total FROM collections{where_sql}", params)
total = cursor.fetchone()["total"]
query_sql = f"""
SELECT * FROM collections{where_sql}
ORDER BY updated_at DESC LIMIT %s OFFSET %s
"""
cursor.execute(query_sql, params + [page_size, offset])
items = cursor.fetchall()
return ApiResponse.success(
PaginatedData.create(items, page, page_size, total)
)
@router.get("/{collection_id}", response_model=ApiResponse)
async def get_collection(collection_id: int):
"""获取单个藏品详情"""
with db.get_cursor() as cursor:
cursor.execute("SELECT * FROM collections WHERE id = %s", (collection_id,))
item = cursor.fetchone()
if not item:
raise HTTPException(status_code=404, detail="Collection not found")
return ApiResponse.success(item)
@router.post("", response_model=ApiResponse, status_code=201)
async def create_collection(collection: CollectionCreate):
"""创建新藏品"""
with db.get_cursor() as cursor:
cursor.execute("""
INSERT INTO collections (
name, category, serial_number, rarity, ownership_type,
is_graded, grading_company, grading_score,
cost_price, current_price, status, remark
) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
""", (
collection.name, collection.category, collection.serial_number,
collection.rarity, collection.ownership_type, collection.is_graded,
collection.grading_company, collection.grading_score,
collection.cost_price, collection.current_price, collection.status, collection.remark
))
new_id = cursor.lastrowid
cursor.execute("SELECT * FROM collections WHERE id = %s", (new_id,))
item = cursor.fetchone()
return ApiResponse.success(item, "Collection created successfully")
@router.put("/{collection_id}", response_model=ApiResponse)
async def update_collection(collection_id: int, collection: CollectionUpdate):
"""更新藏品"""
update_fields = []
params = []
for field, value in collection.model_dump(exclude_unset=True).items():
if value is not None:
update_fields.append(f"{field} = %s")
params.append(value)
if not update_fields:
raise HTTPException(status_code=400, detail="No fields to update")
params.append(collection_id)
set_clause = ", ".join(update_fields)
with db.get_cursor() as cursor:
sql = f"UPDATE collections SET {set_clause}, updated_at = NOW() WHERE id = %s"
cursor.execute(sql, params)
if cursor.rowcount == 0:
raise HTTPException(status_code=404, detail="Collection not found")
cursor.execute("SELECT * FROM collections WHERE id = %s", (collection_id,))
item = cursor.fetchone()
return ApiResponse.success(item, "Collection updated successfully")
@router.delete("/{collection_id}", response_model=ApiResponse)
async def delete_collection(collection_id: int):
"""删除藏品"""
with db.get_cursor() as cursor:
cursor.execute("DELETE FROM collections WHERE id = %s", (collection_id,))
if cursor.rowcount == 0:
raise HTTPException(status_code=404, detail="Collection not found")
return ApiResponse.success(message="Collection deleted successfully")
@router.get("/{collection_id}/prices", response_model=ApiResponse)
async def get_collection_prices(
collection_id: int,
page: int = Query(1, ge=1),
page_size: int = Query(20, ge=1, le=100)
):
"""获取藏品的价柗历史"""
offset = (page - 1) * page_size
with db.get_cursor() as cursor:
cursor.execute("SELECT id FROM collections WHERE id = %s", (collection_id,))
if not cursor.fetchone():
raise HTTPException(status_code=404, detail="Collection not found")
cursor.execute(
"SELECT COUNT(*) as total FROM price_history WHERE collection_id = %s",
(collection_id,)
)
total = cursor.fetchone()["total"]
cursor.execute("""
SELECT * FROM price_history
WHERE collection_id = %s
ORDER BY crawled_at DESC LIMIT %s OFFSET %s
""", (collection_id, page_size, offset))
items = cursor.fetchall()
return ApiResponse.success(
PaginatedData.create(items, page, page_size, total)
)