一键成片优化

This commit is contained in:
Azmat@qq.com
2026-09-04 18:16:43 +08:00
parent ee3ddb49b4
commit 0d042edc73
6 changed files with 130 additions and 7 deletions
@@ -103,7 +103,70 @@ def _script_generation_inflight(project: Project) -> bool:
).exists()
def estimate_quick_create_points(
*,
team,
text_model: ModelConfig,
image_model: ModelConfig,
video_model: ModelConfig,
aspect_ratio: str,
resolution: str,
total_duration: int,
):
"""与前端按钮预估同口径:脚本挂牌 + 默认出图×场次 + 视频挂牌秒价×时长(无引用视频)。"""
from decimal import Decimal
from apps.billing.pricing import quote_flat, quote_video_estimate
scene_count = max(1, int(total_duration) // 15)
script_points = quote_flat(text_model, units=1, team=team).points
image_points = quote_flat(image_model, units=scene_count, team=team).points
_tokens, video_quote = quote_video_estimate(
video_model,
aspect_ratio=aspect_ratio,
resolution=resolution,
duration=int(total_duration),
references=[],
team=team,
)
return Decimal(script_points) + Decimal(image_points) + Decimal(video_quote.points)
def assert_quick_create_balance(
*,
team,
text_model: ModelConfig,
image_model: ModelConfig,
video_model: ModelConfig,
aspect_ratio: str,
resolution: str,
total_duration: int,
):
"""提交前确认可用积分 ≥ 预估总额;不足则抛 ValueError(中文提示)。不预留,只门禁。"""
from decimal import Decimal
from apps.billing.models import CreditAccount
needed = estimate_quick_create_points(
team=team,
text_model=text_model,
image_model=image_model,
video_model=video_model,
aspect_ratio=aspect_ratio,
resolution=resolution,
total_duration=total_duration,
)
account = CreditAccount.objects.filter(team=team).first()
available = (account.balance - account.reserved_balance) if account else Decimal("0")
if available < needed:
raise ValueError(
f"团队余额不足,预计需要 {needed} 积分,当前可用 {available} 积分,请充值后再开始"
)
return needed, available
def get_quick_script_model() -> ModelConfig | None:
"""极速成片固定复用专业创作的豆包 Seed 2.1 Pro 脚本模型。"""
return (
ModelConfig.objects.select_related("provider")
+16
View File
@@ -589,6 +589,22 @@ class ProjectViewSet(TeamScopedViewSetMixin, ModelViewSet):
)
team = self.get_team()
# 开工前门禁:可用积分必须盖住「脚本+出图粗估+视频」挂牌合计(与按钮预估同口径)。
# 不在这里预留整笔,后续各阶段各自 reserve;这里只避免积不够半路挂掉。
from .services.quick_create import assert_quick_create_balance
try:
assert_quick_create_balance(
team=team,
text_model=text_model,
image_model=image_model,
video_model=video_model,
aspect_ratio=aspect_ratio,
resolution=resolution,
total_duration=total_duration,
)
except ValueError as exc:
return Response({"detail": str(exc)}, status=status.HTTP_400_BAD_REQUEST)
reused_assets = []
if source_product_id:
try: