chore: initialize tuhui repository
This commit is contained in:
171
backend/app/api/orders.py
Normal file
171
backend/app/api/orders.py
Normal file
@@ -0,0 +1,171 @@
|
||||
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
|
||||
Reference in New Issue
Block a user