131 lines
3.8 KiB
Python
131 lines
3.8 KiB
Python
"""Admin finance API for avatar Token orders, refunds and invoices."""
|
|
|
|
from fastapi import APIRouter, Body, HTTPException, Query
|
|
|
|
from app.schemas import ApiResponse
|
|
from app.services.avatar_service import get_session, is_available
|
|
from app.services.finance_service import FinanceServiceError, finance_service
|
|
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
def _session():
|
|
if not is_available():
|
|
raise HTTPException(status_code=503, detail="数字分身数据库尚未初始化")
|
|
return get_session()
|
|
|
|
|
|
def _raise(exc: FinanceServiceError):
|
|
raise HTTPException(status_code=exc.status_code, detail=str(exc))
|
|
|
|
|
|
@router.get("/summary")
|
|
def summary():
|
|
db = _session()
|
|
try:
|
|
return ApiResponse(data=finance_service.summary(db))
|
|
finally:
|
|
db.close()
|
|
|
|
|
|
@router.get("/orders")
|
|
def orders(
|
|
page: int = Query(1, ge=1),
|
|
page_size: int = Query(20, ge=1, le=100),
|
|
keyword: str = Query(""),
|
|
status: str = Query(""),
|
|
provider: str = Query(""),
|
|
):
|
|
db = _session()
|
|
try:
|
|
total, items = finance_service.list_orders(
|
|
db, page=page, page_size=page_size, keyword=keyword.strip(), status=status, provider=provider
|
|
)
|
|
return ApiResponse(data={"total": total, "page": page, "page_size": page_size, "items": items})
|
|
finally:
|
|
db.close()
|
|
|
|
|
|
@router.patch("/orders/{order_no}/status")
|
|
def update_order_status(order_no: str, body: dict = Body(...)):
|
|
db = _session()
|
|
try:
|
|
finance_service.close_order(
|
|
db, order_no, status=str(body.get("status") or ""), reason=str(body.get("reason") or "")
|
|
)
|
|
return ApiResponse(message="订单状态已更新")
|
|
except FinanceServiceError as exc:
|
|
_raise(exc)
|
|
finally:
|
|
db.close()
|
|
|
|
|
|
@router.post("/orders/{order_no}/refund")
|
|
def request_refund(order_no: str, body: dict = Body(...)):
|
|
try:
|
|
data = finance_service.request_refund(
|
|
order_no,
|
|
reason=str(body.get("reason") or "").strip(),
|
|
operator=str(body.get("operator") or "后台管理员").strip(),
|
|
)
|
|
return ApiResponse(data=data, message="退款申请已提交")
|
|
except FinanceServiceError as exc:
|
|
_raise(exc)
|
|
|
|
|
|
@router.get("/refunds")
|
|
def refunds(
|
|
page: int = Query(1, ge=1),
|
|
page_size: int = Query(20, ge=1, le=100),
|
|
status: str = Query(""),
|
|
):
|
|
db = _session()
|
|
try:
|
|
total, items = finance_service.list_refunds(db, page=page, page_size=page_size, status=status)
|
|
return ApiResponse(data={"total": total, "page": page, "page_size": page_size, "items": items})
|
|
finally:
|
|
db.close()
|
|
|
|
|
|
@router.post("/refunds/{refund_no}/confirm")
|
|
def confirm_refund(refund_no: str, body: dict = Body(...)):
|
|
try:
|
|
data = finance_service.confirm_refund(refund_no, body)
|
|
return ApiResponse(data=data, message="退款结果已登记")
|
|
except FinanceServiceError as exc:
|
|
_raise(exc)
|
|
|
|
|
|
@router.get("/invoices")
|
|
def invoices(
|
|
page: int = Query(1, ge=1),
|
|
page_size: int = Query(20, ge=1, le=100),
|
|
status: str = Query(""),
|
|
):
|
|
db = _session()
|
|
try:
|
|
total, items = finance_service.list_invoices(db, page=page, page_size=page_size, status=status)
|
|
return ApiResponse(data={"total": total, "page": page, "page_size": page_size, "items": items})
|
|
finally:
|
|
db.close()
|
|
|
|
|
|
@router.patch("/invoices/{invoice_id}")
|
|
def update_invoice(invoice_id: str, body: dict = Body(...)):
|
|
db = _session()
|
|
try:
|
|
finance_service.update_invoice(
|
|
db,
|
|
invoice_id,
|
|
status=str(body.get("status") or ""),
|
|
invoice_no=str(body.get("invoiceNo") or ""),
|
|
invoice_url=str(body.get("invoiceUrl") or ""),
|
|
remark=str(body.get("remark") or ""),
|
|
)
|
|
return ApiResponse(message="发票申请已处理")
|
|
except FinanceServiceError as exc:
|
|
_raise(exc)
|
|
finally:
|
|
db.close()
|