jiachenlong/backend/app/routers/purchase.py

276 lines
8.0 KiB
Python

# purchase - 认购群API路由
# Version: 0.0.1 (2026-04-24)
# 认购群、成员、藏品管理
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.orm import Session
from pydantic import BaseModel
from typing import Optional, List
from datetime import datetime
from app.core.database import get_db
from app.core.auth import get_current_user
from app.models.models import User
from app.models.purchase import PurchaseGroup, PurchaseMember, PurchaseCollection
router = APIRouter(prefix="/api/purchase", tags=["认购"])
# ============ Schema ============
class PurchaseGroupCreate(BaseModel):
name: str
description: Optional[str] = None
class PurchaseGroupResponse(BaseModel):
id: str
name: str
description: Optional[str]
creator_id: str
creator_name: Optional[str]
status: str
total_members: int
total_collections: int
total_amount: float
avg_price: float
created_at: Optional[datetime]
class PurchaseCollectionCreate(BaseModel):
collection_name: str
collection_code: Optional[str] = None
number: Optional[str] = None
price: float
# ============ 认购群API ============
@router.get("/groups", response_model=List[PurchaseGroupResponse])
def get_groups(
status: str = Query("active", description="过滤状态"),
db: Session = Depends(get_db)
):
"""获取所有认购群列表"""
query = db.query(PurchaseGroup)
if status:
query = query.filter(PurchaseGroup.status == status)
groups = query.order_by(PurchaseGroup.created_at.desc()).all()
return groups
@router.get("/my-groups", response_model=List[PurchaseGroupResponse])
def get_my_groups(
current_user = Depends(get_current_user),
db: Session = Depends(get_db)
):
"""获取我参与的认购群"""
member_groups = db.query(PurchaseMember).filter(
PurchaseMember.user_id == current_user.f99_90_id
).all()
group_ids = [m.group_id for m in member_groups]
groups = db.query(PurchaseGroup).filter(
PurchaseGroup.id.in_(group_ids)
).all()
return groups
@router.post("/groups", response_model=PurchaseGroupResponse)
def create_group(
data: PurchaseGroupCreate,
current_user = Depends(get_current_user),
db: Session = Depends(get_db)
):
"""创建认购群(创建者即为群主)"""
if not current_user:
raise HTTPException(status_code=401, detail="请先登录")
group = PurchaseGroup(
name=data.name,
description=data.description,
creator_id=current_user.f99_90_id,
creator_name=current_user.f01_01_name,
status="active"
)
db.add(group)
db.commit()
# 创建者自动加入并成为群主
member = PurchaseMember(
group_id=group.id,
user_id=current_user.f99_90_id,
user_name=current_user.f01_01_name,
user_avatar=current_user.avatar,
role="creator"
)
db.add(member)
db.commit()
db.refresh(group)
return group
@router.get("/groups/{group_id}", response_model=PurchaseGroupResponse)
def get_group(
group_id: str,
db: Session = Depends(get_db)
):
"""获取认购群详情"""
group = db.query(PurchaseGroup).filter(PurchaseGroup.id == group_id).first()
if not group:
raise HTTPException(status_code=404, detail="认购群不存在")
return group
@router.post("/groups/{group_id}/join")
def join_group(
group_id: str,
current_user = Depends(get_current_user),
db: Session = Depends(get_db)
):
"""加入认购群"""
if not current_user:
raise HTTPException(status_code=401, detail="请先登录")
# 检查群是否存在
group = db.query(PurchaseGroup).filter(PurchaseGroup.id == group_id).first()
if not group:
raise HTTPException(status_code=404, detail="认购群不存在")
if group.status != "active":
raise HTTPException(status_code=400, detail="该认购群已结束")
# 检查是否已加入
existing = db.query(PurchaseMember).filter(
PurchaseMember.group_id == group_id,
PurchaseMember.user_id == current_user.f99_90_id
).first()
if existing:
raise HTTPException(status_code=400, detail="您已加入该认购群")
# 加入
member = PurchaseMember(
group_id=group_id,
user_id=current_user.f99_90_id,
user_name=current_user.f01_01_name,
user_avatar=current_user.avatar,
role="member"
)
db.add(member)
# 更新群成员数
group.total_members += 1
db.commit()
return {"message": "加入成功"}
@router.get("/groups/{group_id}/members")
def get_group_members(
group_id: str,
db: Session = Depends(get_db)
):
"""获取认购群成员列表"""
members = db.query(PurchaseMember).filter(
PurchaseMember.group_id == group_id
).order_by(PurchaseMember.joined_at.asc()).all()
return [
{
"id": m.id,
"user_id": m.user_id,
"user_name": m.user_name,
"user_avatar": m.user_avatar,
"role": m.role,
"joined_at": m.joined_at
}
for m in members
]
@router.get("/groups/{group_id}/collections")
def get_group_collections(
group_id: str,
db: Session = Depends(get_db)
):
"""获取认购群藏品列表"""
collections = db.query(PurchaseCollection).filter(
PurchaseCollection.group_id == group_id
).order_by(PurchaseCollection.submitted_at.desc()).all()
return [
{
"id": c.id,
"user_id": c.user_id,
"user_name": c.user_name,
"collection_name": c.collection_name,
"collection_code": c.collection_code,
"number": c.number,
"price": float(c.price),
"status": c.status,
"submitted_at": c.submitted_at
}
for c in collections
]
@router.post("/groups/{group_id}/collections")
def add_collection(
group_id: str,
data: PurchaseCollectionCreate,
current_user = Depends(get_current_user),
db: Session = Depends(get_db)
):
"""提交认购藏品"""
if not current_user:
raise HTTPException(status_code=401, detail="请先登录")
# 检查群是否存在
group = db.query(PurchaseGroup).filter(PurchaseGroup.id == group_id).first()
if not group:
raise HTTPException(status_code=404, detail="认购群不存在")
# 检查是否已加入
member = db.query(PurchaseMember).filter(
PurchaseMember.group_id == group_id,
PurchaseMember.user_id == current_user.f99_90_id
).first()
if not member:
raise HTTPException(status_code=400, detail="请先加入该认购群")
# 添加藏品
collection = PurchaseCollection(
group_id=group_id,
user_id=current_user.f99_90_id,
user_name=current_user.f01_01_name,
collection_name=data.collection_name,
collection_code=data.collection_code,
number=data.number,
price=data.price
)
db.add(collection)
# 更新群统计
group.total_collections += 1
group.total_amount += float(data.price)
if group.total_collections > 0:
group.avg_price = group.total_amount / group.total_collections
db.commit()
db.refresh(collection)
return collection
@router.post("/groups/{group_id}/close")
def close_group(
group_id: str,
current_user = Depends(get_current_user),
db: Session = Depends(get_db)
):
"""结束认购群(仅群主可操作)"""
if not current_user:
raise HTTPException(status_code=401, detail="请先登录")
group = db.query(PurchaseGroup).filter(PurchaseGroup.id == group_id).first()
if not group:
raise HTTPException(status_code=404, detail="认购群不存在")
# 检查是否为群主
if group.creator_id != current_user.f99_90_id:
raise HTTPException(status_code=403, detail="只有群主可以结束认购群")
group.status = "closed"
db.commit()
return {"message": "认购群已结束"}