231 lines
7.1 KiB
Python
231 lines
7.1 KiB
Python
# seek - 寻号匹配路由
|
|
# Version: 0.0.1
|
|
|
|
from fastapi import APIRouter, Depends, Query, HTTPException
|
|
# Version: 1.2.x
|
|
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.seek_info import SeekInfo
|
|
from app.models.models import User
|
|
from app.routers.information import match_collections_count_from_coolbot
|
|
|
|
router = APIRouter(prefix="/api/seek", tags=["寻配号"])
|
|
|
|
# ============ Schema ============
|
|
class SeekInfoCreate(BaseModel):
|
|
title: str
|
|
content: Optional[str] = None
|
|
expect_category: Optional[str] = None
|
|
expect_version: Optional[str] = None
|
|
expect_packaging: Optional[str] = None
|
|
expect_number: Optional[str] = None
|
|
expect_price_min: Optional[float] = None
|
|
expect_price_max: Optional[float] = None
|
|
|
|
class SeekInfoUpdate(BaseModel):
|
|
title: Optional[str] = None
|
|
content: Optional[str] = None
|
|
expect_category: Optional[str] = None
|
|
expect_version: Optional[str] = None
|
|
expect_packaging: Optional[str] = None
|
|
expect_number: Optional[str] = None
|
|
expect_price_min: Optional[float] = None
|
|
expect_price_max: Optional[float] = None
|
|
status: Optional[str] = None
|
|
|
|
class SeekInfoResponse(BaseModel):
|
|
id: str
|
|
user_id: str
|
|
user_name: Optional[str] = None
|
|
network_matched_count: Optional[int] = 0
|
|
title: str
|
|
content: Optional[str]
|
|
expect_category: Optional[str]
|
|
expect_version: Optional[str]
|
|
expect_packaging: Optional[str]
|
|
expect_number: Optional[str]
|
|
expect_price_min: Optional[float]
|
|
expect_price_max: Optional[float]
|
|
status: str
|
|
is_matched: Optional[str]
|
|
matched_user_id: Optional[str]
|
|
matched_contact: Optional[str]
|
|
view_count: int
|
|
contact_count: int
|
|
created_at: Optional[datetime]
|
|
updated_at: Optional[datetime]
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
# ============ API ============
|
|
@router.get("/list", response_model=list[SeekInfoResponse])
|
|
def get_seek_list(
|
|
status: str = Query("active"),
|
|
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(SeekInfo).filter(SeekInfo.status == status)
|
|
|
|
# 我的寻配号:只查看自己的
|
|
if user_only and current_user:
|
|
query = query.filter(SeekInfo.user_id == current_user.f99_90_id)
|
|
|
|
# 排序
|
|
query = query.order_by(SeekInfo.created_at.desc())
|
|
|
|
# 分页
|
|
offset = (page - 1) * page_size
|
|
items = query.offset(offset).limit(page_size).all()
|
|
|
|
# 关联查询用户名
|
|
result = []
|
|
for item in items:
|
|
user = db.query(User).filter(User.f99_90_id == item.user_id).first()
|
|
user_name = user.f01_01_name if user else None
|
|
# 计算网络数据匹配数
|
|
network_matched_count = 0
|
|
if item.expect_number:
|
|
network_matched_count = match_collections_count_from_coolbot(item.expect_number)
|
|
|
|
result.append({
|
|
"id": item.id,
|
|
"user_id": item.user_id,
|
|
"user_name": user_name,
|
|
"title": item.title,
|
|
"content": item.content,
|
|
"expect_category": item.expect_category,
|
|
"expect_version": item.expect_version,
|
|
"expect_packaging": item.expect_packaging,
|
|
"expect_number": item.expect_number,
|
|
"expect_price_min": item.expect_price_min,
|
|
"expect_price_max": item.expect_price_max,
|
|
"status": item.status,
|
|
"is_matched": item.is_matched,
|
|
"matched_user_id": item.matched_user_id,
|
|
"matched_contact": item.matched_contact,
|
|
"view_count": item.view_count,
|
|
"contact_count": item.contact_count,
|
|
"network_matched_count": network_matched_count,
|
|
"created_at": item.created_at.isoformat() if item.created_at else None,
|
|
"updated_at": item.updated_at.isoformat() if item.updated_at else None,
|
|
})
|
|
|
|
return result
|
|
|
|
@router.get("/stats")
|
|
def get_seek_stats(
|
|
current_user = Depends(get_current_user),
|
|
db: Session = Depends(get_db)
|
|
):
|
|
"""获取寻配号统计"""
|
|
total = db.query(SeekInfo).filter(SeekInfo.status == "active").count()
|
|
matched = db.query(SeekInfo).filter(SeekInfo.is_matched == "true").count()
|
|
|
|
return {
|
|
"total": total,
|
|
"matched": matched,
|
|
"unmatched": total - matched
|
|
}
|
|
|
|
@router.post("", response_model=SeekInfoResponse)
|
|
def create_seek(
|
|
data: SeekInfoCreate,
|
|
current_user = Depends(get_current_user),
|
|
db: Session = Depends(get_db)
|
|
):
|
|
"""创建寻配号"""
|
|
if not current_user:
|
|
raise HTTPException(status_code=401, detail="请先登录")
|
|
|
|
seek = SeekInfo(
|
|
user_id=current_user.f99_90_id,
|
|
title=data.title,
|
|
content=data.content,
|
|
expect_category=data.expect_category,
|
|
expect_version=data.expect_version,
|
|
expect_packaging=data.expect_packaging,
|
|
expect_number=data.expect_number,
|
|
expect_price_min=data.expect_price_min,
|
|
expect_price_max=data.expect_price_max,
|
|
status="active"
|
|
)
|
|
db.add(seek)
|
|
db.commit()
|
|
db.refresh(seek)
|
|
return seek
|
|
|
|
@router.get("/{seek_id}", response_model=SeekInfoResponse)
|
|
def get_seek(
|
|
seek_id: str,
|
|
current_user = Depends(get_current_user),
|
|
db: Session = Depends(get_db)
|
|
):
|
|
"""获取寻配号详情"""
|
|
seek = db.query(SeekInfo).filter(SeekInfo.id == seek_id).first()
|
|
if not seek:
|
|
raise HTTPException(status_code=404, detail="寻配号不存在")
|
|
|
|
# 增加浏览数
|
|
seek.view_count += 1
|
|
db.commit()
|
|
|
|
return seek
|
|
|
|
@router.put("/{seek_id}", response_model=SeekInfoResponse)
|
|
def update_seek(
|
|
seek_id: str,
|
|
data: SeekInfoUpdate,
|
|
current_user = Depends(get_current_user),
|
|
db: Session = Depends(get_db)
|
|
):
|
|
"""更新寻配号"""
|
|
if not current_user:
|
|
raise HTTPException(status_code=401, detail="请先登录")
|
|
|
|
seek = db.query(SeekInfo).filter(
|
|
SeekInfo.id == seek_id,
|
|
SeekInfo.user_id == current_user.f99_90_id
|
|
).first()
|
|
|
|
if not seek:
|
|
raise HTTPException(status_code=404, detail="寻配号不存在")
|
|
|
|
for key, value in data.model_dump(exclude_unset=True).items():
|
|
setattr(seek, key, value)
|
|
|
|
db.commit()
|
|
db.refresh(seek)
|
|
return seek
|
|
|
|
@router.delete("/{seek_id}")
|
|
def delete_seek(
|
|
seek_id: str,
|
|
current_user = Depends(get_current_user),
|
|
db: Session = Depends(get_db)
|
|
):
|
|
"""删除寻配号"""
|
|
if not current_user:
|
|
raise HTTPException(status_code=401, detail="请先登录")
|
|
|
|
seek = db.query(SeekInfo).filter(
|
|
SeekInfo.id == seek_id,
|
|
SeekInfo.user_id == current_user.f99_90_id
|
|
).first()
|
|
|
|
if not seek:
|
|
raise HTTPException(status_code=404, detail="寻配号不存在")
|
|
|
|
seek.status = "deleted"
|
|
db.commit()
|
|
|
|
return {"message": "删除成功"}
|