jiachenlong/backend/app/routers/deal.py

248 lines
7.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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": "删除成功"}