This commit is contained in:
sjy
2026-07-01 13:44:19 +08:00
parent 823a58d86f
commit 04f34c1075
5 changed files with 210 additions and 146 deletions
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -28,7 +28,7 @@
}
})();
</script>
<script type="module" crossorigin src="/assets/index-C_zmnmex.js"></script>
<script type="module" crossorigin src="/assets/index-BsNc32TJ.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-BhPFzWLH.css">
</head>
<body>
+6 -2
View File
@@ -338,11 +338,15 @@ export async function getEngine(): Promise<any> {
}
},
default_size: "2K",
priority: 10
priority: 10,
maxImageCount: 4,
maxVideoCount: 0
}
],
video: [
{ id: 'mock', name: 'Seedance', provider: 'seedance', supportedRatios: ['16:9', '9:16', '1:1', '4:3', '3:4', '21:9'], supportedResolutions: ['480p', '720p', '1080p'], supportedDurations: [4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] }
{ id: '0019e1697667d0eff39', name: 'Seedance 2.0', provider: 'ark', model_name: 'seedance-2-0', supportedRatios: ['16:9', '9:16', '1:1', '4:3', '3:4', '21:9'], supportedResolutions: ['480p', '720p', '1080p'], supportedDurations: [4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], maxImageCount: 4, maxVideoCount: 1 },
{ id: '0019e1697667d0eff38', name: 'Seedance 2.0 fast', provider: 'ark', model_name: 'seedance-2-0-fast', supportedRatios: ['16:9', '9:16', '1:1'], supportedResolutions: ['720p', '1080p'], supportedDurations: [5, 8, 10], maxImageCount: 2, maxVideoCount: 1 },
{ id: '0019f1b89b545d8e4b1', name: 'Seedance 2.0 mini', provider: 'ark', model_name: 'seedance-2-0-mini', supportedRatios: ['16:9', '9:16', '1:1'], supportedResolutions: ['480p', '720p'], supportedDurations: [4, 5, 6], maxImageCount: 1, maxVideoCount: 1 }
]
}
};
@@ -143,16 +143,17 @@ const StorageCard: React.FC<{ data: ResourceCapacityData | null }> = ({ data })
color: '#475569',
}}
>
<span style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
{/* <span style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
<DatabaseOutlined style={{ fontSize: 12, color: isOver ? '#ef4444' : '#6366f1' }} />
{rawPercent.toFixed(1)}%
</span>
</span> */}
{data.enabled ? (
<span style={{ fontWeight: 500, color: isOver ? '#ef4444' : '#1e293b' }}>
{used.toFixed(2)} / {total.toFixed(2)} {unit}
</span>
<></>
) : (
<span style={{ fontWeight: 500, color: '#1e293b' }}>
<DatabaseOutlined style={{ fontSize: 12, color: isOver ? '#ef4444' : '#6366f1', marginRight: 4 }} />
使 {usedAuto.val} {usedAuto.unit}
</span>
)}
@@ -162,12 +163,46 @@ const StorageCard: React.FC<{ data: ResourceCapacityData | null }> = ({ data })
<div
style={{
width: '100%',
height: 6,
height: 20,
background: '#e2e8f0',
borderRadius: 3,
overflow: 'hidden',
position: 'relative',
}}
>
<div style={{
position: 'absolute',
top: 0,
left: 0,
height: '100%',
background: 'transparent',
width: '100%',
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
marginBottom: 6,
fontSize: 12,
color: '#000000ff',
padding: '0 8px',
}}>
<span style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
<DatabaseOutlined style={{ fontSize: 12, color: '#000000ff' }} />
{rawPercent.toFixed(1)}%
</span>
{data.enabled ? (
<span style={{ fontWeight: 500, color: isOver ? '#ef4444' : '#000000ff' }}>
{used.toFixed(2)} / {total.toFixed(2)} {unit}
</span>
) : (
<span style={{ fontWeight: 500, color: '#1e293b' }}>
使 {usedAuto.val} {usedAuto.unit}
</span>
)}
</div>
<div
style={{
width: `${barPercent}%`,
@@ -179,6 +214,7 @@ const StorageCard: React.FC<{ data: ResourceCapacityData | null }> = ({ data })
transition: 'width 0.4s ease',
}}
/>
</div>
<div
style={{
@@ -811,9 +847,9 @@ const AppLayout: React.FC = () => {
<span></span>
</div>
{/* 资源存储容量展示(来自 getUser.resourceCapacity */}
<StorageCard data={resourceCapacity} />
<StorageCard data={resourceCapacity} />
<div style={{ padding: '16px 16px', flexShrink: 0 ,paddingTop: 0}}>
<div style={{ padding: '16px 16px', flexShrink: 0, paddingTop: 0 }}>
<Dropdown menu={{ items: userMenuItems, onClick: handleUserMenuClick }} placement="topRight" arrow>
<div style={{
display: 'flex', alignItems: 'center',
+44 -20
View File
@@ -143,6 +143,12 @@ const AIChatPage: React.FC = () => {
setCurrentMedia,
} = useAppStore();
// 获取当前选中引擎的媒体上传限制
const currentEngineList = mediaType === 'image' ? enginesele?.image : enginesele?.video;
const currentEngine = currentEngineList?.find((e: any) => e.id === countType);
const maxImageCount = currentEngine?.maxImageCount ?? 4;
const maxVideoCount = currentEngine?.maxVideoCount ?? 1;
const [uploading, setUploading] = useState<boolean>(false);
const [loading, setLoading] = useState<boolean>(false);
@@ -427,19 +433,19 @@ const AIChatPage: React.FC = () => {
}
}
let supportedSizes = (data as any).engine.image?.[0]?.supportedSizes || {};
let supportedResolutions = [];
let twokwidth = [];
let fourkwidth = [];
let supportedSizes = (data as any).engine?.image?.[0]?.supported_sizes || {};
let supportedResolutions: string[] = [];
let twokwidth: string[] = [];
let fourkwidth: string[] = [];
for (let key in supportedSizes["2K"]) {
supportedResolutions.push(key);
twokwidth.push(supportedSizes["2K"][key]);
}
const newRatioOptions = supportedResolutions.map((res: any, index: number) => ({
const newRatioOptions = supportedResolutions.map((res: any) => ({
value: res,
label: String(index),
label: res,
}));
setRatioOptions(newRatioOptions);
@@ -838,6 +844,18 @@ const AIChatPage: React.FC = () => {
return false;
}
// 获取当前选中引擎的限制
const currentEngineList = mediaType === 'image' ? enginesele.image : enginesele.video;
const currentEngine = currentEngineList?.find((e: any) => e.id === countType);
const maxImage = currentEngine?.maxImageCount ?? 4;
const maxVideo = currentEngine?.maxVideoCount ?? 1;
// 根据 mediaType 判断是否允许该文件类型
if (mediaType === 'image' && isVideo) {
message.error('图片模式仅支持上传图片');
return false;
}
// 验证文件大小
const maxMB = isVideo ? 100 : 10;
if (file.size / 1024 / 1024 > maxMB) {
@@ -845,17 +863,17 @@ const AIChatPage: React.FC = () => {
return false;
}
// 验证图片数量(最多4张)
// 验证图片数量
const imageCount = currentMedia.filter((m) => m.type === 'image').length;
if (isImage && imageCount >= 4) {
message.error('最多上传4张图片');
if (isImage && imageCount >= maxImage) {
message.error(`该引擎最多上传${maxImage}张图片`);
return false;
}
// 验证视频数量(最多1个)
// 验证视频数量
const videoCount = currentMedia.filter((m) => m.type === 'video').length;
if (isVideo && videoCount >= 1) {
message.error('最多上传1个视频');
if (isVideo && videoCount >= maxVideo) {
message.error(`该引擎最多上传${maxVideo}个视频`);
return false;
}
@@ -1092,9 +1110,9 @@ const AIChatPage: React.FC = () => {
border: '1px solid rgba(99, 102, 241, 0.08)',
position: 'relative', overflow: 'hidden', flexWrap: 'wrap', gap: 12,
}}>
<div style={{ display: 'flex', alignItems: 'center', gap: 16 }}>
<div style={{ width: 32, height: 2, background: 'linear-gradient(90deg, transparent, #6366f1, #8b5cf6, transparent)', borderRadius: 1 }} />
<div>
<div style={{ width: '100%', display: 'flex', alignItems: 'center', gap: 16 }}>
<div style={{ width: '15%', height: 2, background: 'linear-gradient(90deg, transparent, #6366f1, #8b5cf6, transparent)', borderRadius: 1 }} />
<div style={{ flex: 1, minWidth: 0, textAlign: 'center' }}>
<h2 style={{
margin: 0,
fontSize: 18,
@@ -1102,7 +1120,7 @@ const AIChatPage: React.FC = () => {
background: 'linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%)',
WebkitBackgroundClip: 'text',
WebkitTextFillColor: 'transparent',
backgroundClip: 'text'
backgroundClip: 'text',
}}>
AI创作
</h2>
@@ -1110,7 +1128,7 @@ const AIChatPage: React.FC = () => {
/
</p>
</div>
<div style={{ width: 32, height: 2, background: 'linear-gradient(90deg, transparent, #8b5cf6, #6366f1, transparent)', borderRadius: 1 }} />
<div style={{ width: '15%', height: 2, background: 'linear-gradient(90deg, transparent, #8b5cf6, #6366f1, transparent)', borderRadius: 1 }} />
</div>
</div>
@@ -1633,11 +1651,14 @@ const AIChatPage: React.FC = () => {
}}>
{/* 上传按钮 */}
<Upload
accept="image/*,video/*"
accept={mediaType === 'image' ? 'image/*' : 'image/*,video/*'}
showUploadList={false}
beforeUpload={handleUpload}
>
<Tooltip title={`图片${currentMedia.filter(m => m.type === 'image').length}/4,视频${currentMedia.filter(m => m.type === 'video').length}/1`}>
<Tooltip title={mediaType === 'image'
? `图片${currentMedia.filter(m => m.type === 'image').length}/${maxImageCount}`
: `图片${currentMedia.filter(m => m.type === 'image').length}/${maxImageCount},视频${currentMedia.filter(m => m.type === 'video').length}/${maxVideoCount}`
}>
<div
style={{
width: 48,
@@ -1679,7 +1700,10 @@ const AIChatPage: React.FC = () => {
onChange={handleInputChange}
onKeyDown={handleInputKeyDown}
onKeyPress={handleKeyPress}
placeholder="上传最多4张参考图,输入提示词描述您想生成的画面..."
placeholder={mediaType === 'image'
? `上传最多${maxImageCount}张参考图,输入提示词描述您想生成的画面...`
: `上传参考图(最多${maxImageCount}张)和视频(最多${maxVideoCount}个),输入提示词描述您想生成的画面...`
}
autoSize={{ minRows: 1, maxRows: 4 }}
style={{
flex: 1,