118 lines
4.4 KiB
Python
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
|