jiachenlong/backend/app/routers/deal.py

248 lines
7.4 KiB
Python
Raw Normal View History

2026-04-15 21:42:52 +08:00
from fastapi import APIRouter, Depends, Query, HTTPException
from sqlalchemy.orm import Session
from pydantic import BaseModel
from typing import Optional
from datetime import datetime, date
from app.core.database import get_db
from app.core.auth import get_current_user
from app.models.deal_info import DealInfo
router = APIRouter(prefix="/api/deal", tags=["成交行情"])
# ============ Schema ============
class DealInfoCreate(BaseModel):
title: str
content: Optional[str] = None
deal_price: Optional[float] = None
deal_date: Optional[str] = None # YYYY-MM-DD
packaging: Optional[str] = None
category: Optional[str] = None
is_graded: Optional[bool] = False
grading_company: Optional[str] = None
grading_score: Optional[str] = None
tail_number: Optional[str] = None
size_type: Optional[str] = None
version: Optional[str] = None
platform: Optional[str] = None
seller: Optional[str] = None
buyer: Optional[str] = None
class DealInfoUpdate(BaseModel):
title: Optional[str] = None
content: Optional[str] = None
deal_price: Optional[float] = None
deal_date: Optional[str] = None
packaging: Optional[str] = None
category: Optional[str] = None
is_graded: Optional[bool] = None
grading_company: Optional[str] = None
grading_score: Optional[str] = None
tail_number: Optional[str] = None
size_type: Optional[str] = None
version: Optional[str] = None
platform: Optional[str] = None
seller: Optional[str] = None
buyer: Optional[str] = None
status: Optional[str] = None
class DealInfoResponse(BaseModel):
id: str
user_id: Optional[str]
title: str
content: Optional[str]
deal_price: Optional[float]
deal_date: Optional[date]
deal_no: Optional[str]
packaging: Optional[str]
category: Optional[str]
is_graded: Optional[bool]
grading_company: Optional[str]
grading_score: Optional[str]
tail_number: Optional[str]
size_type: Optional[str]
version: Optional[str]
platform: Optional[str]
seller: Optional[str]
buyer: Optional[str]
status: str
view_count: int
contact_count: int
created_at: Optional[datetime]
updated_at: Optional[datetime]
class Config:
from_attributes = True
# 生成行情编号
def generate_deal_no(db: Session):
"""生成行情编号从A000001开始递增"""
last = db.query(DealInfo).order_by(DealInfo.deal_no.desc()).first()
if last and last.deal_no:
# 例如 A000001 -> 2 -> A000002
num = int(last.deal_no[1:]) + 1
return f"A{num:06d}"
return "A000001"
# ============ API ============
@router.get("/list", response_model=list[DealInfoResponse])
def get_deal_list(
status: str = Query("active"),
deal_date: Optional[str] = Query(None),
page: int = Query(1, ge=1),
page_size: int = Query(20, ge=1, le=1000),
user_only: bool = Query(False), # 是否只查看自己的
current_user: Optional = Depends(get_current_user),
db: Session = Depends(get_db)
):
"""获取成交行情列表"""
query = db.query(DealInfo).filter(DealInfo.status == status)
# 我的行情:只查看自己的(管理员也只看自己的)
if user_only and current_user:
query = query.filter(DealInfo.user_id == current_user.f99_90_id)
# 成交日期过滤
if deal_date:
query = query.filter(DealInfo.deal_date == deal_date)
# 排序:优先成交日期倒序,同日按编号倒序
query = query.order_by(DealInfo.deal_date.desc().nullslast(), DealInfo.deal_no.desc().nullslast())
# 分页
offset = (page - 1) * page_size
items = query.offset(offset).limit(page_size).all()
return items
@router.get("/stats")
def get_deal_stats(
db: Session = Depends(get_db)
):
"""获取成交行情统计"""
total = db.query(DealInfo).filter(DealInfo.status == "active").count()
# 按日期统计
from sqlalchemy import func
date_stats = db.query(
DealInfo.deal_date,
func.count(DealInfo.id).label('count')
).filter(
DealInfo.status == "active",
DealInfo.deal_date.isnot(None)
).group_by(DealInfo.deal_date).order_by(DealInfo.deal_date.desc()).limit(10).all()
return {
"total": total,
"by_date": [{"date": str(d.deal_date), "count": d.count} for d in date_stats]
}
@router.post("", response_model=DealInfoResponse)
def create_deal(
data: DealInfoCreate,
current_user = Depends(get_current_user),
db: Session = Depends(get_db)
):
"""创建成交行情"""
if not current_user:
raise HTTPException(status_code=401, detail="请先登录")
# 生成行情编号
deal_no = generate_deal_no(db)
# 解析日期
deal_date = None
if data.deal_date:
try:
deal_date = datetime.strptime(data.deal_date, "%Y-%m-%d").date()
except:
pass
deal = DealInfo(
user_id=current_user.f99_90_id if current_user else None,
title=data.title,
content=data.content,
deal_price=data.deal_price,
deal_date=deal_date,
deal_no=deal_no,
packaging=data.packaging,
category=data.category,
is_graded=data.is_graded or False,
grading_company=data.grading_company,
grading_score=data.grading_score,
tail_number=data.tail_number,
size_type=data.size_type,
version=data.version,
platform=data.platform,
seller=data.seller,
buyer=data.buyer,
status="active"
)
db.add(deal)
db.commit()
db.refresh(deal)
return deal
@router.get("/{deal_id}", response_model=DealInfoResponse)
def get_deal(
deal_id: str,
current_user = Depends(get_current_user),
db: Session = Depends(get_db)
):
"""获取成交行情详情"""
deal = db.query(DealInfo).filter(DealInfo.id == deal_id).first()
if not deal:
raise HTTPException(status_code=404, detail="成交行情不存在")
# 增加浏览数
deal.view_count += 1
db.commit()
return deal
@router.put("/{deal_id}", response_model=DealInfoResponse)
def update_deal(
deal_id: str,
data: DealInfoUpdate,
current_user = Depends(get_current_user),
db: Session = Depends(get_db)
):
"""更新成交行情"""
if not current_user:
raise HTTPException(status_code=401, detail="请先登录")
deal = db.query(DealInfo).filter(DealInfo.id == deal_id).first()
if not deal:
raise HTTPException(status_code=404, detail="成交行情不存在")
# 处理日期
if data.deal_date:
try:
data.deal_date = datetime.strptime(data.deal_date, "%Y-%m-%d").date()
except:
data.deal_date = None
for key, value in data.model_dump(exclude_unset=True).items():
setattr(deal, key, value)
db.commit()
db.refresh(deal)
return deal
@router.delete("/{deal_id}")
def delete_deal(
deal_id: str,
current_user = Depends(get_current_user),
db: Session = Depends(get_db)
):
"""删除成交行情"""
if not current_user:
raise HTTPException(status_code=401, detail="请先登录")
deal = db.query(DealInfo).filter(DealInfo.id == deal_id).first()
if not deal:
raise HTTPException(status_code=404, detail="成交行情不存在")
deal.status = "deleted"
db.commit()
return {"message": "删除成功"}