from fastapi import APIRouter, Depends, HTTPException, status, Header from sqlalchemy.orm import Session from datetime import datetime, timedelta import secrets from app.core.database import get_db from app.core.security import decode_access_token from app.models.user import User from app.models.work import Work from app.models.order import Order, OrderStatus from app.models.download import DownloadRecord from app.schemas.order import OrderCreate, OrderResponse, PaymentResponse router = APIRouter(prefix="/orders", tags=["订单"]) def get_current_user(authorization: str = Header(None), db: Session = Depends(get_db)): """获取当前登录用户""" if not authorization or not authorization.startswith("Bearer "): raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="未登录" ) token = authorization.replace("Bearer ", "") payload = decode_access_token(token) if not payload: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Token 无效或已过期" ) user_id = int(payload.get("sub")) user = db.query(User).filter(User.id == user_id).first() if not user: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="用户不存在" ) return user @router.post("/create", response_model=OrderResponse, summary="创建订单") def create_order( order_data: OrderCreate, current_user: User = Depends(get_current_user), db: Session = Depends(get_db) ): """创建下载订单""" # 查找作品 work = db.query(Work).filter(Work.id == order_data.work_id).first() if not work: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="作品不存在" ) # 检查是否已购买 existing_order = db.query(Order).filter( Order.user_id == current_user.id, Order.work_id == work.id, Order.status == OrderStatus.PAID ).first() if existing_order: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="您已购买过此作品" ) # 生成订单号:前缀 + (当前时间-6个月)的年月日 + 当前时间的时分秒 now = datetime.now() six_months_ago = now - timedelta(days=180) # 半年前 date_part = six_months_ago.strftime('%Y%m%d') # 半年前的年月日 time_part = now.strftime('%H%M%S') # 当前时间的时分秒 order_no = f"ORD{date_part}{time_part}" # 创建订单 new_order = Order( order_no=order_no, user_id=current_user.id, work_id=work.id, amount=work.price, payment_method=order_data.payment_method, status=OrderStatus.PENDING ) db.add(new_order) db.commit() db.refresh(new_order) return new_order @router.post("/pay/{order_id}", response_model=PaymentResponse, summary="支付订单") def pay_order( order_id: int, current_user: User = Depends(get_current_user), db: Session = Depends(get_db) ): """ 支付订单(模拟支付) 实际生产环境需要对接真实支付接口 """ # 查找订单 order = db.query(Order).filter( Order.id == order_id, Order.user_id == current_user.id ).first() if not order: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="订单不存在" ) if order.status != OrderStatus.PENDING: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="订单状态异常" ) # 余额支付 if order.payment_method == "balance": if current_user.balance < order.amount: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="余额不足" ) # 扣除余额 current_user.balance -= order.amount # 更新订单状态 order.status = OrderStatus.PAID order.paid_at = datetime.now() # 创建下载记录 download_record = DownloadRecord( user_id=current_user.id, work_id=order.work_id, order_id=order.id ) db.add(download_record) # 增加作品下载量 work = db.query(Work).filter(Work.id == order.work_id).first() work.downloads += 1 db.commit() return PaymentResponse( success=True, message="支付成功", order_no=order.order_no, download_url=f"/api/works/{work.id}/download" ) # 其他支付方式(支付宝、微信) else: return PaymentResponse( success=False, message="暂不支持该支付方式,请使用余额支付或联系管理员", order_no=order.order_no ) @router.get("/my", summary="我的订单") def get_my_orders( current_user: User = Depends(get_current_user), db: Session = Depends(get_db) ): """获取当前用户的订单列表""" orders = db.query(Order).filter(Order.user_id == current_user.id).all() return orders