fix(generation): exclude asset refs from image upload limit
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 7m20s

This commit is contained in:
zyc 2026-05-25 16:26:03 +08:00
parent a08234e54b
commit 92701ed558
3 changed files with 14 additions and 14 deletions

View File

@ -359,8 +359,12 @@ def video_generate_view(request):
}, status=status.HTTP_429_TOO_MANY_REQUESTS) }, status=status.HTTP_429_TOO_MANY_REQUESTS)
# 构建参考素材 # 构建参考素材
# 火山限制最多 9 张参考图片 # 直接上传的参考图片最多 9 张;素材库 asset:// 引用不计入该上传槽位限制。
image_count = sum(1 for r in references if r.get('type', 'image') == 'image') image_count = sum(
1 for r in references
if r.get('type', 'image') == 'image'
and not str(r.get('url', '')).startswith('asset://')
)
if image_count > 9: if image_count > 9:
return Response({ return Response({
'error': 'too_many_references', 'error': 'too_many_references',

View File

@ -416,14 +416,15 @@ export function PromptInput() {
}, [extractText]); }, [extractText]);
const insertAssetMention = useCallback((asset: AssetSearchResult) => { const insertAssetMention = useCallback((asset: AssetSearchResult) => {
// Instant check: count limit // Instant check: count limit. Image assets from the library do not consume
// the 9 direct-upload image slots.
const stats = editorRef.current ? parseAssetMentionsFromDOM(editorRef.current) : { counts: { image: 0, video: 0, audio: 0 }, durations: { video: 0, audio: 0 } }; const stats = editorRef.current ? parseAssetMentionsFromDOM(editorRef.current) : { counts: { image: 0, video: 0, audio: 0 }, durations: { video: 0, audio: 0 } };
const refs = useInputBarStore.getState().references; const refs = useInputBarStore.getState().references;
const refCounts = { image: 0, video: 0, audio: 0 }; const refCounts = { image: 0, video: 0, audio: 0 };
refs.forEach((r) => refCounts[r.type]++); refs.forEach((r) => refCounts[r.type]++);
const typeKey = asset.asset_type === 'Video' ? 'video' : asset.asset_type === 'Audio' ? 'audio' : 'image'; const typeKey = asset.asset_type === 'Video' ? 'video' : asset.asset_type === 'Audio' ? 'audio' : 'image';
const maxMap = { image: 9, video: 3, audio: 3 }; const maxMap = { video: 3, audio: 3 };
if (refCounts[typeKey] + stats.counts[typeKey] >= maxMap[typeKey]) { if (typeKey !== 'image' && refCounts[typeKey] + stats.counts[typeKey] >= maxMap[typeKey]) {
const typeLabel = asset.asset_type === 'Video' ? '视频' : asset.asset_type === 'Audio' ? '音频' : '图片'; const typeLabel = asset.asset_type === 'Video' ? '视频' : asset.asset_type === 'Audio' ? '音频' : '图片';
showToast(`${typeLabel}已达上限`); showToast(`${typeLabel}已达上限`);
return; return;

View File

@ -261,13 +261,10 @@ export const useInputBarStore = create<InputBarState>((set, get) => ({
prevReferences: [], prevReferences: [],
addReferences: (files) => { addReferences: (files) => {
const state = get(); const state = get();
// Count existing references by type + merge @ asset mentions // Count direct uploaded references by type. Asset library mentions do not
// consume direct upload slots.
const counts = { image: 0, video: 0, audio: 0 }; const counts = { image: 0, video: 0, audio: 0 };
for (const ref of state.references) counts[ref.type]++; for (const ref of state.references) counts[ref.type]++;
const { counts: assetCounts } = parseAssetMentions(state.editorHtml);
counts.image += assetCounts.image;
counts.video += assetCounts.video;
counts.audio += assetCounts.audio;
// Separate images (sync) from audio/video (need async duration check) // Separate images (sync) from audio/video (need async duration check)
const imageFiles: File[] = []; const imageFiles: File[] = [];
@ -559,8 +556,7 @@ async function _validateAndAddImages(files: File[]) {
// Passed — add to store + upload // Passed — add to store + upload
fileCounter++; fileCounter++;
const existingSameType = state.references.filter(r => r.type === 'image').length const existingSameType = state.references.filter(r => r.type === 'image').length;
+ (state.assetMentions || []).filter((m: Record<string, string>) => m.type === 'image').length;
const refId = `ref_${fileCounter}`; const refId = `ref_${fileCounter}`;
const newRef: UploadedFile = { const newRef: UploadedFile = {
id: refId, id: refId,
@ -659,8 +655,7 @@ async function _validateAndAddMedia(files: File[]) {
// Passed all checks — add to store // Passed all checks — add to store
fileCounter++; fileCounter++;
const labelPrefix = type === 'video' ? '视频' : '音频'; const labelPrefix = type === 'video' ? '视频' : '音频';
const existingSameType = state.references.filter(r => r.type === type).length const existingSameType = state.references.filter(r => r.type === type).length;
+ (state.assetMentions || []).filter((m: Record<string, string>) => m.type === type).length;
const refId = `ref_${fileCounter}`; const refId = `ref_${fileCounter}`;
const newRef: UploadedFile = { const newRef: UploadedFile = {
id: refId, id: refId,