fix: 音频不能作为唯一参考素材 — 前端校验 + toast 提示
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 6m0s

Seedance API 不支持"纯音频"和"文本+音频"输入,必须搭配图片或视频。
- canSubmit() 校验同时检查 references 和 assetMentions
- Toolbar 点击禁用按钮时弹出 toast 提示原因

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
seaislee1209 2026-04-14 14:10:39 +08:00
parent 41115faa16
commit 2281c64ee8
2 changed files with 22 additions and 5 deletions

View File

@ -3,6 +3,7 @@ import { useInputBarStore } from '../store/inputBar';
import { useGenerationStore } from '../store/generation';
import { useAuthStore } from '../store/auth';
import { Dropdown } from './Dropdown';
import { showToast } from './Toast';
import type { CreationMode, AspectRatio, Duration, GenerationType, ModelOption } from '../types';
import styles from './Toolbar.module.css';
@ -145,7 +146,14 @@ export function Toolbar() {
}, [estimatedTokens, model, references, team]);
const handleSend = useCallback(() => {
if (!isSubmittable) return;
if (!isSubmittable) {
const s = useInputBarStore.getState();
if (s.mode === 'universal' && s.references.some((r) => r.type === 'audio')
&& !s.references.some((r) => r.type === 'image' || r.type === 'video')) {
showToast('音频不能作为唯一的参考素材,请同时添加图片或视频');
}
return;
}
addTask();
}, [isSubmittable, addTask]);

View File

@ -285,10 +285,19 @@ export const useInputBarStore = create<InputBarState>((set, get) => ({
? state.references.length > 0
: state.firstFrame !== null || state.lastFrame !== null;
if (!hasText && !hasFiles) return false;
// Audio cannot be sent alone — must have image or video
if (state.mode === 'universal' && state.references.length > 0) {
const hasImageOrVideo = state.references.some((r) => r.type === 'image' || r.type === 'video');
if (!hasImageOrVideo && !hasText) return false;
// Audio cannot be the only reference — Seedance API requires image or video alongside
if (state.mode === 'universal') {
const hasAudioRef = state.references.some((r) => r.type === 'audio');
const hasAudioAsset = (state.assetMentions || []).some((m: Record<string, string>) =>
(m.assetType || '').toLowerCase() === 'audio');
if (hasAudioRef || hasAudioAsset) {
const hasImageOrVideoRef = state.references.some((r) => r.type === 'image' || r.type === 'video');
const hasImageOrVideoAsset = (state.assetMentions || []).some((m: Record<string, string>) => {
const t = (m.assetType || '').toLowerCase();
return t === 'image' || t === 'video';
});
if (!hasImageOrVideoRef && !hasImageOrVideoAsset) return false;
}
}
// Block submit if any reference is still uploading or failed
if (state.references.some((r) => r.uploading || r.uploadError)) return false;