2026-04-19 21:34:14 +08:00
|
|
|
# news - 新闻路由
|
2026-04-19 22:22:45 +08:00
|
|
|
# Version: 0.0.1
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
|
|
|
|
|
2026-03-31 01:22:34 +08:00
|
|
|
from fastapi import APIRouter, Depends, HTTPException, Query
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
|
|
|
|
# Version: 1.2.x
|
|
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
from sqlalchemy import Table, MetaData
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
from sqlalchemy.orm import Session
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
from pydantic import BaseModel
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
from typing import Optional, List
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
from datetime import datetime, date
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
from app.core.database import get_db, engine
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
from app.models.models import User
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
from app.routers.auth import get_current_user
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
router = APIRouter(prefix="/api/news", tags=["资讯"])
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
metadata = MetaData()
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
# 分类表
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
categories_table = Table('news_categories', metadata, autoload_with=engine)
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
news_table = Table('news', metadata, autoload_with=engine)
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
user_posts_table = Table('user_posts', metadata, autoload_with=engine)
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
users_table = Table('users', metadata, autoload_with=engine)
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
deals_table = Table('deals', metadata, autoload_with=engine)
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
notifications_table = Table('notifications', metadata, autoload_with=engine)
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
# ============ 获取分类 ============
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
@router.get("/categories")
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
def get_categories(db: Session = Depends(get_db)):
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
results = db.query(categories_table).order_by(categories_table.c.sort_order).all()
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
return [dict(r._mapping) for r in results]
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
# ============ 获取资讯 ============
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
@router.get("")
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
def get_news(
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
category_id: Optional[int] = None,
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
page: int = 1,
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
limit: int = 20,
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
db: Session = Depends(get_db)
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
):
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
query = db.query(news_table)
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
if category_id:
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
query = query.filter(news_table.c.category_id == category_id)
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
offset = (page - 1) * limit
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
results = query.order_by(news_table.c.created_at.desc()).offset(offset).limit(limit).all()
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
return [dict(r._mapping) for r in results]
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
# ============ 获取用户发布 ============
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
@router.get("/posts")
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
def get_posts(
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
post_type: Optional[str] = None,
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
status: str = "active",
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
page: int = 1,
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
limit: int = 20,
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
db: Session = Depends(get_db)
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
):
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
query = db.query(user_posts_table).filter(user_posts_table.c.status == status)
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
if post_type:
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
query = query.filter(user_posts_table.c.post_type == post_type)
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
offset = (page - 1) * limit
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
results = query.order_by(user_posts_table.c.created_at.desc()).offset(offset).limit(limit).all()
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
return [dict(r._mapping) for r in results]
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
# ============ 创建发布 ============
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
class PostCreate(BaseModel):
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
post_type: str
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
title: str
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
content: Optional[str] = None
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
zodiac_type: Optional[str] = None
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
packaging: Optional[str] = None
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
@router.post("/posts")
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
def create_post(
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
post: PostCreate,
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
current_user: User = Depends(get_current_user),
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
db: Session = Depends(get_db)
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
):
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
result = db.execute(user_posts_table.insert().values(
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
user_id=current_user.f99_90_id,
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
post_type=post.post_type,
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
title=post.title,
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
content=post.content,
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
zodiac_type=post.zodiac_type,
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
packaging=post.packaging,
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
status="pending"
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
))
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
db.commit()
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
return {"success": True, "id": result.inserted_primary_key[0]}
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
# ============ 成交数据 ============
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
@router.get("/deals")
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
def get_deals(
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
zodiac_type: Optional[str] = None,
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
limit: int = 20,
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
db: Session = Depends(get_db)
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
):
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
query = db.query(deals_table)
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
if zodiac_type:
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
query = query.filter(deals_table.c.zodiac_type == zodiac_type)
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
results = query.order_by(deals_table.c.deal_date.desc()).limit(limit).all()
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
return [dict(r._mapping) for r in results]
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
# ============ 通知 ============
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
@router.get("/notifications")
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
def get_notifications(limit: int = 10, db: Session = Depends(get_db)):
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
results = db.query(notifications_table).filter(
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
notifications_table.c.is_published == True
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
).order_by(notifications_table.c.created_at.desc()).limit(limit).all()
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
return [dict(r._mapping) for r in results]
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
# ============ 首页数据 ============
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
@router.get("/home")
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
def get_home(db: Session = Depends(get_db)):
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
# 推荐发布
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
posts = db.query(user_posts_table).filter(
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
user_posts_table.c.status == "active"
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
).order_by(user_posts_table.c.created_at.desc()).limit(10).all()
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
# 成交
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
deals = db.query(deals_table).order_by(
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
deals_table.c.deal_date.desc()
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
).limit(10).all()
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
# 通知
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
notices = db.query(notifications_table).filter(
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
notifications_table.c.is_published == True
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
).order_by(notifications_table.c.created_at.desc()).limit(5).all()
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
return {
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
"posts": [dict(p._mapping) for p in posts],
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
"deals": [dict(d._mapping) for d in deals],
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
"notices": [dict(n._mapping) for n in notices]
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|
2026-03-31 01:22:34 +08:00
|
|
|
}
|
2026-04-19 21:34:14 +08:00
|
|
|
# 更新:
|