Files
video-gen/video-gen-api/app/api/v1/credits.py
T
2026-07-01 10:10:43 +08:00

118 lines
4.4 KiB
Python

from fastapi import APIRouter, Depends, Query
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select
from app.dependencies import get_db, get_current_user
from app.models.user import User
from app.models.credit_ratio import CreditRatio
from app.models.video_engine import VideoEngine
from app.models.image_engine import ImageEngine
from app.schemas.credit import CreditBalanceOut, CreditRecordOut
from app.schemas.credit_ratio import CreditRatioOut
from app.services.credit_ratio_service import list_all_credit_ratios
from app.services.credits import get_records
router = APIRouter(prefix="/credits", tags=["credits"])
@router.get("")
async def get_credits(
page: int = Query(1, ge=1),
page_size: int = Query(20, ge=1, le=100),
current_user: User = Depends(get_current_user),
db: AsyncSession = Depends(get_db),
):
records, total = await get_records(db, current_user.id, page, page_size)
return {
"credits": round(current_user.credits, 2),
"records": [CreditRecordOut.model_validate(r) for r in records],
"total": total,
}
@router.get(
"/credit-ratios",
response_model=list[CreditRatioOut],
summary="获取积分比例列表",
description="客户端获取当前系统配置的积分计费规则列表。普通登录用户可访问,只读返回 credit_ratios 表中的图片/视频积分比例配置。",
)
async def list_client_credit_ratios(
current_user: User = Depends(get_current_user),
db: AsyncSession = Depends(get_db),
):
return await list_all_credit_ratios(db)
@router.get("/ratios", response_model=dict)
async def get_credit_ratios(
current_user: User = Depends(get_current_user),
db: AsyncSession = Depends(get_db),
):
import json
async def get_engine_with_ratios(gen_type: str, engines: list):
for engine in engines:
result = await db.execute(
select(CreditRatio)
.where(CreditRatio.gen_type == gen_type)
.where(CreditRatio.model_config_id == engine.id)
)
ratios = result.scalars().all()
if ratios:
ratios_out = [CreditRatioOut.model_validate(r) for r in ratios]
engine_info = {
"id": engine.id,
"name": engine.name,
"provider": engine.provider,
"ratios": ratios_out,
}
if gen_type == "video":
try:
supported_ratios = json.loads(engine.supported_ratios) if engine.supported_ratios else []
except Exception:
supported_ratios = []
try:
supported_resolutions = json.loads(engine.supported_resolutions) if engine.supported_resolutions else []
except Exception:
supported_resolutions = []
try:
supported_durations = json.loads(engine.supported_durations) if engine.supported_durations else []
except Exception:
supported_durations = []
engine_info.update({
"supported_ratios": supported_ratios,
"supported_resolutions": supported_resolutions,
"supported_durations": supported_durations,
"max_duration": engine.max_duration,
"max_image_count": engine.max_image_count,
"max_video_count": engine.max_video_count,
})
return engine_info
return None
video_engines_result = await db.execute(
select(VideoEngine)
.where(VideoEngine.is_active == True)
.order_by(VideoEngine.priority.desc())
)
video_engines = video_engines_result.scalars().all()
image_engines_result = await db.execute(
select(ImageEngine)
.where(ImageEngine.is_active == True)
.order_by(ImageEngine.priority.desc())
)
image_engines = image_engines_result.scalars().all()
grouped = {}
video_data = await get_engine_with_ratios("video", video_engines)
if video_data:
grouped["video"] = video_data
image_data = await get_engine_with_ratios("image", image_engines)
if image_data:
grouped["image"] = image_data
return grouped