From 7a0be57227d5fcba0b82c2b50606d4aac1e1e560 Mon Sep 17 00:00:00 2001 From: seaislee1209 Date: Wed, 25 Mar 2026 00:47:23 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20v0.13.1=20=E7=83=82=E5=9B=BE=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=20+=20=E9=A2=9D=E5=BA=A6=E6=A3=80=E6=9F=A5=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 【烂图修复】 ①backendToFrontend 过滤空 URL 引用 ②@ 弹窗音频显示音符符号而非烂图 ③hover 预览音频显示音符而非烂图 ④视频详情空 previewUrl 显示「无预览」 【额度检查修正】 ⑤spending_limit 检查:已完成用 cost_amount,处理中用 frozen_amount ⑥超限提示改为显示总额度/已消费/剩余/本次预估 Co-Authored-By: Claude Opus 4.6 (1M context) --- backend/apps/generation/views.py | 12 ++++++++---- web/src/components/PromptInput.tsx | 6 +++++- web/src/components/VideoDetailModal.tsx | 4 +++- web/src/store/generation.ts | 4 +++- 4 files changed, 19 insertions(+), 7 deletions(-) diff --git a/backend/apps/generation/views.py b/backend/apps/generation/views.py index 640ef39..a421a5f 100644 --- a/backend/apps/generation/views.py +++ b/backend/apps/generation/views.py @@ -204,14 +204,18 @@ def video_generate_view(request): # Layer 2.5: 用户总消费额度 (skip if -1) from decimal import Decimal if user.spending_limit != Decimal('-1'): - total_spent = GenerationRecord.objects.filter( - user=user, - status__in=['completed', 'processing', 'queued'], + # 已完成的用 cost_amount,处理中/排队的用 frozen_amount(预估费用) + completed_cost = GenerationRecord.objects.filter( + user=user, status='completed', ).aggregate(total=Sum('cost_amount'))['total'] or Decimal('0') + pending_cost = GenerationRecord.objects.filter( + user=user, status__in=['processing', 'queued'], + ).aggregate(total=Sum('frozen_amount'))['total'] or Decimal('0') + total_spent = completed_cost + pending_cost if total_spent + estimated_cost > user.spending_limit: return Response({ 'error': 'spending_limit_exceeded', - 'message': f'您的总消费已达上限(¥{user.spending_limit}),请联系管理员', + 'message': f'余额不足,总额度 ¥{user.spending_limit},已消费 ¥{total_spent:.2f},剩余 ¥{(user.spending_limit - total_spent):.2f},本次预估 ¥{estimated_cost:.2f}', 'spending_limit': float(user.spending_limit), 'total_spent': float(total_spent), }, status=status.HTTP_429_TOO_MANY_REQUESTS) diff --git a/web/src/components/PromptInput.tsx b/web/src/components/PromptInput.tsx index e41cac9..3006140 100644 --- a/web/src/components/PromptInput.tsx +++ b/web/src/components/PromptInput.tsx @@ -616,13 +616,15 @@ export function PromptInput() {
{ref.type === 'video' ? (
{ref.label} - {ref.type === 'video' ? '视频' : '图片'} + {ref.type === 'video' ? '视频' : ref.type === 'audio' ? '音频' : '图片'} ))} @@ -671,6 +673,8 @@ export function PromptInput() { playsInline className={styles.previewMedia} /> + ) : hoverRef.type === 'audio' ? ( +
{'\u266B'}
) : ( - ) : ( + ) : ref.previewUrl ? ( {ref.label} setLightboxSrc(ref.previewUrl)} /> + ) : ( +
无预览
)} {ref.label} diff --git a/web/src/store/generation.ts b/web/src/store/generation.ts index c4b0b48..94ae86a 100644 --- a/web/src/store/generation.ts +++ b/web/src/store/generation.ts @@ -62,7 +62,9 @@ function backendToFrontend(bt: BackendTask): GenerationTask { const references: ReferenceSnapshot[] = allRefs .filter((ref) => { const url = ref.url || ''; - return !url.startsWith('asset://') && !url.startsWith('Asset://'); + if (!url || url.trim() === '') return false; + if (url.startsWith('asset://') || url.startsWith('Asset://')) return false; + return true; }) .map((ref, i) => ({ id: `ref_${bt.task_id}_${i}`,