行业提词优化,积分不足判断

This commit is contained in:
sjy
2026-07-23 17:41:44 +08:00
parent 7ea612d374
commit d5cb11dc60
8 changed files with 1556 additions and 1977 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1 -3
View File
@@ -1,4 +1,3 @@
<!doctype html> <!doctype html>
<html lang="zh-CN"> <html lang="zh-CN">
<head> <head>
@@ -29,11 +28,10 @@
} }
})(); })();
</script> </script>
<script type="module" crossorigin src="/assets/index-BhfopyFy.js"></script> <script type="module" crossorigin src="/assets/index-5mDsoYNB.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-Bsz_Xon-.css"> <link rel="stylesheet" crossorigin href="/assets/index-Bsz_Xon-.css">
</head> </head>
<body> <body>
<div id="root"></div> <div id="root"></div>
</body> </body>
</html> </html>
@@ -43,11 +43,17 @@ interface ProgressItemProps {
isPending: boolean; isPending: boolean;
isCompleted: boolean; isCompleted: boolean;
onAnimationComplete?: () => void; onAnimationComplete?: () => void;
index?: number;
} }
const PROGRESS_RATE = 0.6; const PROGRESS_RATE = 0.6;
const calculateProgressValue = (createdAt?: string): number => { const seededRandom = (seed: number): number => {
const x = Math.sin(seed * 9999) * 10000;
return x - Math.floor(x);
};
const calculateProgressValue = (createdAt?: string, index: number = 0): number => {
if (!createdAt) return 0; if (!createdAt) return 0;
const createdTime = new Date(createdAt).getTime(); const createdTime = new Date(createdAt).getTime();
if (isNaN(createdTime)) return 0; if (isNaN(createdTime)) return 0;
@@ -56,18 +62,24 @@ const calculateProgressValue = (createdAt?: string): number => {
if (elapsedSeconds >= MAX_DURATION_SECONDS) { if (elapsedSeconds >= MAX_DURATION_SECONDS) {
return 99; return 99;
} }
return Math.min(99, elapsedSeconds * PROGRESS_RATE); let progress = Math.min(99, elapsedSeconds * PROGRESS_RATE);
const baseOffset = index * 3;
const randomOffset = seededRandom(index + 1) * 8;
const offset = baseOffset + randomOffset;
progress = Math.max(0, progress - offset);
return progress;
}; };
const ProgressItem: React.FC<ProgressItemProps> = ({ item, isPending: isPendingProp, isCompleted, onAnimationComplete }) => { const ProgressItem: React.FC<ProgressItemProps> = ({ item, isPending: isPendingProp, isCompleted, onAnimationComplete, index = 0 }) => {
const [displayProgress, setDisplayProgress] = useState<number>(0); const [displayProgress, setDisplayProgress] = useState<number>(0);
const [isFinishing, setIsFinishing] = useState(false); const [isFinishing, setIsFinishing] = useState(false);
const intervalRef = useRef<number | null>(null); const intervalRef = useRef<number | null>(null);
useEffect(() => { useEffect(() => {
const newProgress = calculateProgressValue(item.createdAt); if (isFinishing) return;
const newProgress = calculateProgressValue(item.createdAt, index);
setDisplayProgress(newProgress); setDisplayProgress(newProgress);
}, [item]); }, [item, index, isFinishing]);
useEffect(() => { useEffect(() => {
if (isCompleted && !isFinishing) { if (isCompleted && !isFinishing) {
@@ -84,7 +96,8 @@ const ProgressItem: React.FC<ProgressItemProps> = ({ item, isPending: isPendingP
} }
const updateProgress = () => { const updateProgress = () => {
const newProgress = calculateProgressValue(item.createdAt); if (isFinishing) return;
const newProgress = calculateProgressValue(item.createdAt, index);
setDisplayProgress(newProgress); setDisplayProgress(newProgress);
}; };
@@ -96,7 +109,7 @@ const ProgressItem: React.FC<ProgressItemProps> = ({ item, isPending: isPendingP
intervalRef.current = null; intervalRef.current = null;
} }
}; };
}, [item.createdAt, isPendingProp, isCompleted, isFinishing, item.id]); }, [item.createdAt, isPendingProp, isCompleted, isFinishing, item.id, index]);
useEffect(() => { useEffect(() => {
if (isFinishing) { if (isFinishing) {
@@ -305,7 +318,7 @@ const GenerationTaskResourceGrid: React.FC<Props> = ({ task, onPreview, resolveU
{pending || isFinishing ? <span className="gen-task-aurora-3" /> : null} {pending || isFinishing ? <span className="gen-task-aurora-3" /> : null}
{pending || isFinishing ? <LoadingOutlined spin style={{ color: '#8b5cf6', fontSize: items.length > 2 ? 20 : 34 }} /> : <WarningOutlined style={{ color: displayStatus === 'deleted' ? '#98A2B3' : '#A45B5B', fontSize: items.length > 2 ? 20 : 34 }} />} {pending || isFinishing ? <LoadingOutlined spin style={{ color: '#8b5cf6', fontSize: items.length > 2 ? 20 : 34 }} /> : <WarningOutlined style={{ color: displayStatus === 'deleted' ? '#98A2B3' : '#A45B5B', fontSize: items.length > 2 ? 20 : 34 }} />}
<span style={{ fontSize: items.length > 2 ? 10 : 12, color: pending || isFinishing ? '#8b5cf6' : (displayStatus === 'deleted' ? '#98A2B3' : '#A45B5B'), fontWeight: 500 }}>{statusLabel}</span> <span style={{ fontSize: items.length > 2 ? 10 : 12, color: pending || isFinishing ? '#8b5cf6' : (displayStatus === 'deleted' ? '#98A2B3' : '#A45B5B'), fontWeight: 500 }}>{statusLabel}</span>
<ProgressItem item={item} isPending={pending || isFinishing} isCompleted={completed} onAnimationComplete={() => handleFinishAnimation(itemId)} /> <ProgressItem item={item} isPending={pending || isFinishing} isCompleted={completed} onAnimationComplete={() => handleFinishAnimation(itemId)} index={item.generationIndex || index} />
{!pending && item.errorMessage && items.length <= 2 ? <span style={{ fontSize: 10, color: '#A45B5B', lineHeight: 1.3, maxHeight: 28, overflow: 'hidden' }}>{item.errorMessage}</span> : null} {!pending && item.errorMessage && items.length <= 2 ? <span style={{ fontSize: 10, color: '#A45B5B', lineHeight: 1.3, maxHeight: 28, overflow: 'hidden' }}>{item.errorMessage}</span> : null}
</div> </div>
)} )}
File diff suppressed because it is too large Load Diff
+86 -70
View File
@@ -32,7 +32,7 @@ function buildAssetUrl(url?: string): string {
function RemoveInfo() { function RemoveInfo() {
const { creatID } = useParams<{ creatID: string }>(); const { creatID } = useParams<{ creatID: string }>();
const navigate = useNavigate(); const navigate = useNavigate();
const { user } = useAuthStore(); const { user, optimizeHoldCredits } = useAuthStore();
const [drawerVisible, setDrawerVisible] = useState(false); const [drawerVisible, setDrawerVisible] = useState(false);
const [trimModalVisible, setTrimModalVisible] = useState(false); const [trimModalVisible, setTrimModalVisible] = useState(false);
const [currentSegment, setCurrentSegment] = useState<string | null>(null); const [currentSegment, setCurrentSegment] = useState<string | null>(null);
@@ -316,19 +316,19 @@ function RemoveInfo() {
const params = { const params = {
target_project_name: productName.trim(), target_project_name: productName.trim(),
core_content_point: productSellingPoint.trim(), core_content_point: productSellingPoint.trim(),
project_description: productSellingPoint.trim() || undefined, project_description: productSellingPoint.trim() || undefined,
material_image_url: productImage || undefined, material_image_url: productImage || undefined,
material_image_resource_id: productImageResourceId || undefined, material_image_resource_id: productImageResourceId || undefined,
video_config: { video_config: {
engine_id: engineId, engine_id: engineId,
duration: videoDuration, duration: videoDuration,
aspect_ratio: videoAspectRatio, aspect_ratio: videoAspectRatio,
resolution: videoResolution, resolution: videoResolution,
}, },
idempotency_key: idempotencyKey, idempotency_key: idempotencyKey,
}; };
setLoading(true); setLoading(true);
@@ -640,7 +640,7 @@ function RemoveInfo() {
fixed: 'right', fixed: 'right',
align: 'center' as const, align: 'center' as const,
render: (_: any, record: any) => ( render: (_: any, record: any) => (
<div style={{ display: 'flex', alignItems: 'center', gap: 8 }}> <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
{record.moduleProjectId ? ( {record.moduleProjectId ? (
<Button <Button
type="text" type="text"
@@ -792,34 +792,34 @@ function RemoveInfo() {
</div> </div>
</div> </div>
</div> </div>
{taskDetail.analysisStatus === 'failed' && ( {taskDetail.analysisStatus === 'failed' && (
<div style={{ marginTop: 12, textAlign: 'center' }}> <div style={{ marginTop: 12, textAlign: 'center' }}>
<Button <Button
onClick={handleReanalyze} onClick={handleReanalyze}
style={{ style={{
width: "100%", width: "100%",
padding: '6px 16px', padding: '6px 16px',
borderRadius: 8, borderRadius: 8,
fontSize: 12, fontSize: 12,
border: '1px solid #ef4444', border: '1px solid #ef4444',
color: '#ef4444', color: '#ef4444',
background: 'rgba(239, 68, 68, 0.05)', background: 'rgba(239, 68, 68, 0.05)',
cursor: taskDetail.analysisStatus === 'processing' ? 'not-allowed' : 'pointer', cursor: taskDetail.analysisStatus === 'processing' ? 'not-allowed' : 'pointer',
transition: 'all 0.2s', transition: 'all 0.2s',
}} }}
onMouseEnter={(e) => { onMouseEnter={(e) => {
if (taskDetail.analysisStatus !== 'processing') { if (taskDetail.analysisStatus !== 'processing') {
e.currentTarget.style.background = 'rgba(239, 68, 68, 0.1)'; e.currentTarget.style.background = 'rgba(239, 68, 68, 0.1)';
} }
}} }}
onMouseLeave={(e) => { onMouseLeave={(e) => {
e.currentTarget.style.background = 'rgba(239, 68, 68, 0.05)'; e.currentTarget.style.background = 'rgba(239, 68, 68, 0.05)';
}} }}
> >
{taskDetail.analysisStatus === 'processing' ? '分析中...' : '重新分析'} {taskDetail.analysisStatus === 'processing' ? '分析中...' : '重新分析'}
</Button> </Button>
</div> </div>
)} )}
</div> </div>
@@ -1521,34 +1521,50 @@ function RemoveInfo() {
</div> </div>
<div style={{ display: 'flex', gap: 12, marginTop: 8 }}> <div style={{ display: 'flex', gap: 12, marginTop: 8 }}>
<Button <Tooltip
type="primary" title={((user?.credits || 0) < (estimatedCredits + optimizeHoldCredits)) ? '积分不足,请更换参数/充值积分' : ''}
onClick={() => { placement="top"
if ((user?.credits || 0) < estimatedCredits) {
message.warning('积分不足,请更换参数/充值积分');
return;
}
handleManualGenerate();
}}
loading={loading}
disabled={loading || !engineId || !selectedEngineSupportsImage || ((user?.credits || 0) < estimatedCredits)}
style={{
flex: 1,
height: 44,
borderRadius: 12,
fontWeight: 600,
fontSize: 15,
border: 'none',
background: 'linear-gradient(135deg, #6366f1 0%, #8b5cf6 50%, #a855f7 100%)',
boxShadow: '0 4px 16px rgba(99, 102, 241, 0.3)',
transition: 'all 0.25s cubic-bezier(0.4, 0, 0.2, 1)',
}}
> >
{loading ? '生成中...' : '手动生成'} <Button
<span style={{ color: '#fff', marginLeft: 8, fontSize: 13 }}> type="primary"
:{estimatedCredits}
</span> onClick={() => {
</Button> if ((user?.credits || 0) < (estimatedCredits + optimizeHoldCredits)) {
message.warning('积分不足,请更换参数/充值积分');
return;
}
handleManualGenerate();
}}
loading={loading}
// disabled={loading || !engineId || !selectedEngineSupportsImage || ((user?.credits || 0) < (estimatedCredits + optimizeHoldCredits))}
style={{
flex: 1,
height: 44,
borderRadius: 12,
fontWeight: 600,
fontSize: 15,
border: 'none',
background: 'linear-gradient(135deg, #6366f1 0%, #8b5cf6 50%, #a855f7 100%)',
boxShadow: '0 4px 16px rgba(99, 102, 241, 0.3)',
transition: 'all 0.25s cubic-bezier(0.4, 0, 0.2, 1)',
}}
>
{loading ? '生成中...' : '手动生成'}
</Button>
</Tooltip>
</div>
<div style={{ textAlign: 'center' }}>
<span style={{ color: '#000000ff', marginLeft: 8, fontSize: 13 }}>
:{estimatedCredits}
</span>
<span style={{ color: '#000000ff', marginLeft: 8, fontSize: 13 }}>
+
</span>
<span style={{ color: '#000000ff', marginLeft: 8, fontSize: 13 }}>
:{optimizeHoldCredits}
</span>
</div> </div>
</div> </div>
</Drawer> </Drawer>
+70 -49
View File
@@ -88,10 +88,10 @@ function InitialInfo() {
if (previewVisible && previewType === 'video') { if (previewVisible && previewType === 'video') {
const playVideo = () => { const playVideo = () => {
if (videoRef.current) { if (videoRef.current) {
videoRef.current.play().catch(() => {}); videoRef.current.play().catch(() => { });
} }
}; };
if (videoRef.current) { if (videoRef.current) {
if (videoRef.current.readyState >= 2) { if (videoRef.current.readyState >= 2) {
playVideo(); playVideo();
@@ -99,9 +99,9 @@ function InitialInfo() {
videoRef.current.addEventListener('loadedmetadata', playVideo); videoRef.current.addEventListener('loadedmetadata', playVideo);
} }
} }
const timer = setTimeout(playVideo, 300); const timer = setTimeout(playVideo, 300);
return () => { return () => {
clearTimeout(timer); clearTimeout(timer);
if (videoRef.current) { if (videoRef.current) {
@@ -145,7 +145,7 @@ function InitialInfo() {
// 当apiSteps更新时,逆向遍历找到第一个已完成或失败的步骤并展开 // 当apiSteps更新时,逆向遍历找到第一个已完成或失败的步骤并展开
useEffect(() => { useEffect(() => {
const completedFailedKeys = new Set<string>(); const completedFailedKeys = new Set<string>();
activeKey.forEach(key => { activeKey.forEach(key => {
const step = steps.find(s => String(s.childId) === key); const step = steps.find(s => String(s.childId) === key);
if (step && (step.status === 'completed' || step.status === 'failed')) { if (step && (step.status === 'completed' || step.status === 'failed')) {
@@ -291,7 +291,7 @@ function InitialInfo() {
useEffect(() => { useEffect(() => {
calculateCredits().then((data: any) => { calculateCredits().then((data: any) => {
setCreditCalculationData(data); setCreditCalculationData(data);
}).catch(() => {}); }).catch(() => { });
}, []); }, []);
const calculateEstimatedCredits = () => { const calculateEstimatedCredits = () => {
@@ -317,7 +317,7 @@ function InitialInfo() {
} }
let total = (videoDuration * config.perSecondCredits + config.baseCredits) * config.ratio; let total = (videoDuration * config.perSecondCredits + config.baseCredits) * config.ratio;
const inputVideoDuration = taskDetail?.videoGeneration?.inputMedia?.video?.duration || 0; const inputVideoDuration = taskDetail?.videoGeneration?.inputMedia?.video?.duration || 0;
if (inputVideoDuration > 0) { if (inputVideoDuration > 0) {
const inputVideoCost = ((config.inputVideoBaseCredits || 0) + (config.inputVideoPerSecondCredits || 0) * inputVideoDuration) * (config.inputVideoRatio || 1); const inputVideoCost = ((config.inputVideoBaseCredits || 0) + (config.inputVideoPerSecondCredits || 0) * inputVideoDuration) * (config.inputVideoRatio || 1);
@@ -367,7 +367,7 @@ function InitialInfo() {
} }
let total = (duration * config.perSecondCredits + config.baseCredits) * config.ratio; let total = (duration * config.perSecondCredits + config.baseCredits) * config.ratio;
const inputVideoDuration = taskDetail?.videoGeneration?.inputMedia?.video?.duration || 0; const inputVideoDuration = taskDetail?.videoGeneration?.inputMedia?.video?.duration || 0;
if (inputVideoDuration > 0) { if (inputVideoDuration > 0) {
const inputVideoCost = ((config.inputVideoBaseCredits || 0) + (config.inputVideoPerSecondCredits || 0) * inputVideoDuration) * (config.inputVideoRatio || 1); const inputVideoCost = ((config.inputVideoBaseCredits || 0) + (config.inputVideoPerSecondCredits || 0) * inputVideoDuration) * (config.inputVideoRatio || 1);
@@ -564,12 +564,12 @@ function InitialInfo() {
} }
removetwo(taskDetail.id, steps[1].id.toString(), params).then((res: any) => { removetwo(taskDetail.id, steps[1].id.toString(), params).then((res: any) => {
message.info('正在生成图片,请稍候...'); message.info('正在生成图片,请稍候...');
refreshTaskDetail(); refreshTaskDetail();
}).catch((error: any) => { }).catch((error: any) => {
const errorMsg = error?.message?.split(': ')?.[1] || error?.message || '生成失败'; const errorMsg = error?.message?.split(': ')?.[1] || error?.message || '生成失败';
message.error(errorMsg); message.error(errorMsg);
}); });
} }
@@ -788,7 +788,7 @@ function InitialInfo() {
<div className="medio_box" style={{ aspectRatio: '16/9', background: 'linear-gradient(135deg, rgba(248,250,252,0.8) 0%, rgba(238,242,255,0.6) 100%)', borderRadius: 14, overflow: 'hidden', boxShadow: '0 4px 12px rgba(99, 102, 241, 0.06)', border: '1px solid rgba(99, 102, 241, 0.08)', cursor: taskDetail?.material?.materialVideoUrl ? 'pointer' : 'default' }} onClick={() => taskDetail?.material?.materialVideoUrl && openPreview(taskDetail.material.materialVideoUrl, 'video')}> <div className="medio_box" style={{ aspectRatio: '16/9', background: 'linear-gradient(135deg, rgba(248,250,252,0.8) 0%, rgba(238,242,255,0.6) 100%)', borderRadius: 14, overflow: 'hidden', boxShadow: '0 4px 12px rgba(99, 102, 241, 0.06)', border: '1px solid rgba(99, 102, 241, 0.08)', cursor: taskDetail?.material?.materialVideoUrl ? 'pointer' : 'default' }} onClick={() => taskDetail?.material?.materialVideoUrl && openPreview(taskDetail.material.materialVideoUrl, 'video')}>
{taskDetail?.material?.materialVideoUrl ? ( {taskDetail?.material?.materialVideoUrl ? (
<video <video
src={buildMediaUrl(taskDetail.material.materialVideoUrl)} src={buildMediaUrl(taskDetail.material.materialVideoUrl)}
style={{ width: '100%', height: '100%', objectFit: 'contain' }} style={{ width: '100%', height: '100%', objectFit: 'contain' }}
/> />
@@ -837,7 +837,7 @@ function InitialInfo() {
</span> </span>
<div className="medio_box" style={{ aspectRatio: '16/9', background: 'linear-gradient(135deg, rgba(248,250,252,0.8) 0%, rgba(238,242,255,0.6) 100%)', borderRadius: 14, overflow: 'hidden', boxShadow: '0 4px 12px rgba(99, 102, 241, 0.06)', border: '1px solid rgba(99, 102, 241, 0.08)', cursor: 'pointer' }} onClick={() => openPreview(taskDetail.finalVideoUrl, 'video')}> <div className="medio_box" style={{ aspectRatio: '16/9', background: 'linear-gradient(135deg, rgba(248,250,252,0.8) 0%, rgba(238,242,255,0.6) 100%)', borderRadius: 14, overflow: 'hidden', boxShadow: '0 4px 12px rgba(99, 102, 241, 0.06)', border: '1px solid rgba(99, 102, 241, 0.08)', cursor: 'pointer' }} onClick={() => openPreview(taskDetail.finalVideoUrl, 'video')}>
<video <video
src={`${import.meta.env.VITE_API_BASE || "http://localhost:8000"}${taskDetail.finalVideoUrl}`} src={`${import.meta.env.VITE_API_BASE || "http://localhost:8000"}${taskDetail.finalVideoUrl}`}
style={{ width: '100%', height: '100%', objectFit: 'contain' }} style={{ width: '100%', height: '100%', objectFit: 'contain' }}
/> />
@@ -956,11 +956,7 @@ function InitialInfo() {
)} )}
</div> </div>
</div> </div>
<Button onClick={() => { createone(step.id); }} type="primary" style={{ flex: 1, borderRadius: 10, background: 'linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%)', border: 'none', height: 36, fontWeight: 500, boxShadow: '0 4px 12px rgba(99, 102, 241, 0.3)' }} disabled={step.status !== 'completed'}>
</Button>
</div> </div>
<div> <div>
<div style={{ marginBottom: 8 }}> <div style={{ marginBottom: 8 }}>
<span style={{ fontSize: 12, fontWeight: 500, color: '#666666', marginRight: 8 }}></span> <span style={{ fontSize: 12, fontWeight: 500, color: '#666666', marginRight: 8 }}></span>
@@ -970,12 +966,37 @@ function InitialInfo() {
<span style={{ fontSize: 12, fontWeight: 500, color: '#666666', marginRight: 8 }}></span> <span style={{ fontSize: 12, fontWeight: 500, color: '#666666', marginRight: 8 }}></span>
<span style={{ fontSize: 13, color: '#4b5563' }}>{steps[0]?.input?.payload?.targetProjectName || '-'}</span> <span style={{ fontSize: 13, color: '#4b5563' }}>{steps[0]?.input?.payload?.targetProjectName || '-'}</span>
</div> </div>
<div> <div style={{ marginBottom: 8 }}>
<span style={{ fontSize: 12, fontWeight: 500, color: '#666666', marginRight: 8 }}></span> <span style={{ fontSize: 12, fontWeight: 500, color: '#666666', marginRight: 8 }}></span>
<span style={{ fontSize: 13, color: '#4b5563' }}>{steps[0]?.input?.payload?.coreContentPoint || '-'}</span> <span style={{ fontSize: 13, color: '#4b5563' }}>{steps[0]?.input?.payload?.coreContentPoint || '-'}</span>
</div> </div>
</div> </div>
{!isV2 && (
<Tooltip
title={((user?.credits || 0) < optimizeHoldCredits) ? `积分不足${optimizeHoldCredits},请充值积分` : ''}
placement="top"
>
<Button
onClick={() => {
if ((user?.credits || 0) < optimizeHoldCredits) {
message.warning(`积分不足${optimizeHoldCredits},请充值积分`);
return;
}
createone(step.id);
}}
type="primary"
style={{ width: '100%', borderRadius: 10, background: 'linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%)', border: 'none', height: 36, fontWeight: 500, boxShadow: '0 4px 12px rgba(99, 102, 241, 0.3)' }}
disabled={step.status !== 'completed' || ((user?.credits || 0) < optimizeHoldCredits)}
>
</Button>
</Tooltip>
)}
</> </>
)} )}
{/* 步骤2: 生成提示词 */} {/* 步骤2: 生成提示词 */}
@@ -996,7 +1017,7 @@ function InitialInfo() {
> >
</Button> </Button>
<Button onClick={() => { createimage(step.id); }} type="primary" style={{ flex: 1, borderRadius: 10, background: 'linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%)', border: 'none', height: 36, fontWeight: 500, boxShadow: '0 4px 12px rgba(99, 102, 241, 0.3)' }} disabled={step.status !== 'completed'}> <Button onClick={() => { createimage(step.id); }} type="primary" style={{ flex: 1, borderRadius: 10, background: 'linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%)', border: 'none', height: 36, fontWeight: 500, boxShadow: '0 4px 12px rgba(99, 102, 241, 0.3)' }} disabled={step.status !== 'completed'}>
</Button> </Button>
</Space> </Space>
@@ -1401,21 +1422,21 @@ function InitialInfo() {
> >
<Button <Button
type="primary" type="primary"
style={{ style={{
width: '100%', width: '100%',
borderRadius: 10, borderRadius: 10,
background: 'linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%)', background: 'linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%)',
border: 'none', border: 'none',
height: 36, height: 36,
fontWeight: 500, fontWeight: 500,
boxShadow: '0 4px 12px rgba(99, 102, 241, 0.3)' boxShadow: '0 4px 12px rgba(99, 102, 241, 0.3)'
}} }}
onClick={() => { onClick={() => {
if ((user?.credits || 0) < estimatedCredits) { if ((user?.credits || 0) < estimatedCredits) {
message.warning('积分不足,请更换参数/充值积分'); message.warning('积分不足,请更换参数/充值积分');
return; return;
} }
handleNextStep(step.id); handleNextStep(step.id);
}} }}
disabled={step.status !== 'completed' || ((user?.credits || 0) < estimatedCredits)} disabled={step.status !== 'completed' || ((user?.credits || 0) < estimatedCredits)}
> >
@@ -1465,7 +1486,7 @@ function InitialInfo() {
})()} })()}
</div> </div>
</div> </div>
<Space style={{ marginTop: 16, gap: 12, width: '100%', flexWrap: 'wrap' }}> <Space style={{ marginTop: 16, gap: 12, width: '100%', flexWrap: 'wrap' }}>
<Button <Button
@@ -1499,26 +1520,26 @@ function InitialInfo() {
</Button> </Button>
</Tooltip> </Tooltip>
)} )}
<Tooltip <Tooltip
title={((user?.credits || 0) < calculateCreditsFromVideoConfig()) ? `积分不足${calculateCreditsFromVideoConfig()},请充值积分` : ''} title={((user?.credits || 0) < calculateCreditsFromVideoConfig()) ? `积分不足${calculateCreditsFromVideoConfig()},请充值积分` : ''}
placement="top" placement="top"
>
<Button
onClick={() => {
const credits = calculateCreditsFromVideoConfig();
if ((user?.credits || 0) < credits) {
message.warning(`积分不足${credits},请充值积分`);
return;
}
createvideo(step.id, step.engineId);
}}
type="primary"
style={{ flex: '1 0 auto', minWidth: 140, borderRadius: 10, background: 'linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%)', border: 'none', height: 36, fontWeight: 500, boxShadow: '0 4px 12px rgba(99, 102, 241, 0.3)' }}
disabled={step.status !== 'completed' || ((user?.credits || 0) < calculateCreditsFromVideoConfig())}
> >
<Button ({calculateCreditsFromVideoConfig()})
onClick={() => { </Button>
const credits = calculateCreditsFromVideoConfig(); </Tooltip>
if ((user?.credits || 0) < credits) {
message.warning(`积分不足${credits},请充值积分`);
return;
}
createvideo(step.id, step.engineId);
}}
type="primary"
style={{ flex: '1 0 auto', minWidth: 140, borderRadius: 10, background: 'linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%)', border: 'none', height: 36, fontWeight: 500, boxShadow: '0 4px 12px rgba(99, 102, 241, 0.3)' }}
disabled={step.status !== 'completed' || ((user?.credits || 0) < calculateCreditsFromVideoConfig())}
>
({calculateCreditsFromVideoConfig()})
</Button>
</Tooltip>
</Space> </Space>
</> </>
)} )}