fix: keep upload access in direct workflow mode
This commit is contained in:
parent
076e4f55e6
commit
90b6cd442c
@ -160,6 +160,7 @@ const MAX_CHAT_HIDDEN_PROMPT_LENGTH = 4000;
|
||||
const MAX_CHAT_ATTACHMENT_NAME_LENGTH = 100;
|
||||
const MAX_AGENT_MODE_QUERY_LENGTH = 64;
|
||||
const MAX_AGENT_MODE_REFERENCE_COUNT = 40;
|
||||
const DIRECT_MODEL_UPLOAD_SLOT_COUNT = 4;
|
||||
const CHAT_UUID_REGEX =
|
||||
/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
||||
const ALLOWED_CHAT_MEDIA_TYPES = new Set([
|
||||
@ -1274,6 +1275,19 @@ export function AgentGenerationWorkspaceDarkV2({
|
||||
},
|
||||
[hasAgentUploadSlots, modelSlotEnabled, modelSlotIndex, productSlotCount]
|
||||
);
|
||||
const isDirectReferenceUploadEnabled = isDirectModelGenerationMode && !hasMaterialStep;
|
||||
const directReferenceUploadSlots = useMemo(
|
||||
() =>
|
||||
Array.from({ length: DIRECT_MODEL_UPLOAD_SLOT_COUNT }, (_, index) => ({
|
||||
slotIndex: index,
|
||||
label: `参考图${index + 1}`,
|
||||
})),
|
||||
[]
|
||||
);
|
||||
const visibleAttachmentUploadSlots = isDirectReferenceUploadEnabled
|
||||
? directReferenceUploadSlots
|
||||
: agentUploadSlots;
|
||||
const hasVisibleAttachmentUploadSlots = visibleAttachmentUploadSlots.length > 0;
|
||||
const requiredProductUploadCount = hasAgentUploadSlots ? productSlotCount : 0;
|
||||
const detailReferenceTarget = presetModeConfig.detail.referenceImageSource;
|
||||
const skuReferenceTarget = presetModeConfig.sku.referenceImageSource;
|
||||
@ -1383,6 +1397,13 @@ export function AgentGenerationWorkspaceDarkV2({
|
||||
});
|
||||
}
|
||||
|
||||
if (isDirectReferenceUploadEnabled) {
|
||||
return attachments
|
||||
.slice(0, DIRECT_MODEL_UPLOAD_SLOT_COUNT)
|
||||
.map((attachment) => sanitizeChatAttachment(attachment))
|
||||
.filter((attachment): attachment is PickedAttachment => Boolean(attachment));
|
||||
}
|
||||
|
||||
if (!isSceneGenerationPreset) {
|
||||
return attachments
|
||||
.map((attachment) => sanitizeChatAttachment(attachment))
|
||||
@ -1439,6 +1460,7 @@ export function AgentGenerationWorkspaceDarkV2({
|
||||
attachments,
|
||||
hasMaterialStep,
|
||||
isDirectModelGenerationMode,
|
||||
isDirectReferenceUploadEnabled,
|
||||
isSceneGenerationPreset,
|
||||
referenceImages,
|
||||
scenePrimaryReferenceCount,
|
||||
@ -1451,7 +1473,11 @@ export function AgentGenerationWorkspaceDarkV2({
|
||||
requiredProductUploadCount - filledProductAttachmentCount,
|
||||
0
|
||||
);
|
||||
const directReferenceAttachmentCount = attachments
|
||||
.slice(0, DIRECT_MODEL_UPLOAD_SLOT_COUNT)
|
||||
.filter((item) => Boolean(item?.url)).length;
|
||||
const productAttachmentSummary = `${selectedProductAttachments.length}/${productSlotCount} 张产品图`;
|
||||
const directReferenceAttachmentSummary = `已上传 ${directReferenceAttachmentCount}/${DIRECT_MODEL_UPLOAD_SLOT_COUNT} 张参考图`;
|
||||
const modelAttachmentSummary = modelSlotEnabled
|
||||
? selectedModelAttachment
|
||||
? "模特图已带入"
|
||||
@ -2576,10 +2602,14 @@ export function AgentGenerationWorkspaceDarkV2({
|
||||
}, [activeResultModeUrls, selectedResultUrl]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isDirectReferenceUploadEnabled) {
|
||||
setIsAttachmentSlotExpanded(true);
|
||||
return;
|
||||
}
|
||||
if (!selectedAgentPresetId || !hasAgentUploadSlots) {
|
||||
setIsAttachmentSlotExpanded(false);
|
||||
}
|
||||
}, [hasAgentUploadSlots, selectedAgentPresetId]);
|
||||
}, [hasAgentUploadSlots, isDirectReferenceUploadEnabled, selectedAgentPresetId]);
|
||||
|
||||
useEffect(() => {
|
||||
if (requiresPresetSelection && !selectedAgentPresetId) {
|
||||
@ -2653,7 +2683,7 @@ export function AgentGenerationWorkspaceDarkV2({
|
||||
}, [addNode, latestGeneratedGroup, nodes.length, syncGeneratedResultsToCanvas]);
|
||||
|
||||
const updateAttachmentAtSlot = useCallback((slotIndex: number, attachment: PickedAttachment | null) => {
|
||||
const slotCount = Math.max(agentUploadSlots.length, 1);
|
||||
const slotCount = Math.max(visibleAttachmentUploadSlots.length, 1);
|
||||
setAttachments((current) => {
|
||||
const slots: Array<PickedAttachment | null> = Array.from(
|
||||
{ length: slotCount },
|
||||
@ -2662,7 +2692,7 @@ export function AgentGenerationWorkspaceDarkV2({
|
||||
slots[slotIndex] = attachment;
|
||||
return slots;
|
||||
});
|
||||
}, [agentUploadSlots.length]);
|
||||
}, [visibleAttachmentUploadSlots.length]);
|
||||
|
||||
const handleSlotFileChange = useCallback(
|
||||
async (slotIndex: number, event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
@ -2688,7 +2718,7 @@ export function AgentGenerationWorkspaceDarkV2({
|
||||
contentType: file.type || "image/jpeg",
|
||||
assetId: typeof data.assetId === "string" ? data.assetId : undefined,
|
||||
});
|
||||
toast.success(`${agentUploadSlots[slotIndex]?.label || `槽位${slotIndex + 1}`}上传成功`);
|
||||
toast.success(`${visibleAttachmentUploadSlots[slotIndex]?.label || `槽位${slotIndex + 1}`}上传成功`);
|
||||
} catch (error) {
|
||||
toast.error(error instanceof Error ? error.message : "上传失败");
|
||||
} finally {
|
||||
@ -2696,7 +2726,7 @@ export function AgentGenerationWorkspaceDarkV2({
|
||||
event.currentTarget.value = "";
|
||||
}
|
||||
},
|
||||
[agentUploadSlots, updateAttachmentAtSlot]
|
||||
[updateAttachmentAtSlot, visibleAttachmentUploadSlots]
|
||||
);
|
||||
const handleBatchDownloadImages = useCallback(async (params: {
|
||||
imageUrls: string[];
|
||||
@ -4244,43 +4274,56 @@ export function AgentGenerationWorkspaceDarkV2({
|
||||
<div className="space-y-3">
|
||||
<div className="flex items-center gap-2 text-sm font-semibold text-white">
|
||||
<ImagePlus className="h-4 w-4 text-emerald-300" />
|
||||
输入图槽位
|
||||
{isDirectReferenceUploadEnabled ? "上传参考图" : "输入图槽位"}
|
||||
</div>
|
||||
|
||||
{agentUploadSlots.length > 0 ? (
|
||||
{hasVisibleAttachmentUploadSlots ? (
|
||||
<>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
<span
|
||||
className={cn(
|
||||
"rounded-full border px-3 py-1 text-xs",
|
||||
attachmentSummaryReady
|
||||
? "border-emerald-400/25 bg-emerald-500/[0.10] text-emerald-100"
|
||||
: "border-amber-400/25 bg-amber-500/[0.10] text-amber-100"
|
||||
)}
|
||||
>
|
||||
{productAttachmentSummary}
|
||||
</span>
|
||||
{modelAttachmentSummary ? (
|
||||
{isDirectReferenceUploadEnabled ? (
|
||||
<div className="flex flex-wrap gap-2">
|
||||
<span className="rounded-full border border-emerald-400/25 bg-emerald-500/[0.10] px-3 py-1 text-xs text-emerald-100">
|
||||
{directReferenceAttachmentSummary}
|
||||
</span>
|
||||
<span className="rounded-full border border-white/10 bg-black/20 px-3 py-1 text-xs text-white/60">
|
||||
可选上传,也可纯文字生成
|
||||
</span>
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex flex-wrap gap-2">
|
||||
<span
|
||||
className={cn(
|
||||
"rounded-full border px-3 py-1 text-xs",
|
||||
selectedModelAttachment
|
||||
attachmentSummaryReady
|
||||
? "border-emerald-400/25 bg-emerald-500/[0.10] text-emerald-100"
|
||||
: "border-white/10 bg-black/20 text-white/60"
|
||||
: "border-amber-400/25 bg-amber-500/[0.10] text-amber-100"
|
||||
)}
|
||||
>
|
||||
{modelAttachmentSummary}
|
||||
{productAttachmentSummary}
|
||||
</span>
|
||||
) : null}
|
||||
<span className="rounded-full border border-white/10 bg-black/20 px-3 py-1 text-xs text-white/60">
|
||||
共 {agentUploadSlots.length} 个输入槽位
|
||||
</span>
|
||||
</div>
|
||||
{modelAttachmentSummary ? (
|
||||
<span
|
||||
className={cn(
|
||||
"rounded-full border px-3 py-1 text-xs",
|
||||
selectedModelAttachment
|
||||
? "border-emerald-400/25 bg-emerald-500/[0.10] text-emerald-100"
|
||||
: "border-white/10 bg-black/20 text-white/60"
|
||||
)}
|
||||
>
|
||||
{modelAttachmentSummary}
|
||||
</span>
|
||||
) : null}
|
||||
<span className="rounded-full border border-white/10 bg-black/20 px-3 py-1 text-xs text-white/60">
|
||||
共 {agentUploadSlots.length} 个输入槽位
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<p className="text-xs leading-6 text-white/55">
|
||||
{missingAttachmentCount > 0
|
||||
? `当前还需补充 ${missingAttachmentCount} 张产品图,展开后可继续检查或替换。`
|
||||
: "产品图已自动带入并准备完成;模特图槽位可按需补充,不选也可以继续生成。"}
|
||||
{isDirectReferenceUploadEnabled
|
||||
? "第一步和第二步关闭时,可在这里直接上传商品图、参考图或场景图;生成时会和补充要求一起发送给模型。"
|
||||
: missingAttachmentCount > 0
|
||||
? `当前还需补充 ${missingAttachmentCount} 张产品图,展开后可继续检查或替换。`
|
||||
: "产品图已自动带入并准备完成;模特图槽位可按需补充,不选也可以继续生成。"}
|
||||
</p>
|
||||
</>
|
||||
) : (
|
||||
@ -4290,14 +4333,20 @@ export function AgentGenerationWorkspaceDarkV2({
|
||||
)}
|
||||
</div>
|
||||
|
||||
{agentUploadSlots.length > 0 ? (
|
||||
{hasVisibleAttachmentUploadSlots ? (
|
||||
<CollapsibleTrigger asChild>
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
className="border-white/12 bg-black/25 text-white/82 hover:border-white/22 hover:bg-white/[0.06] hover:text-white"
|
||||
>
|
||||
{isAttachmentSlotExpanded ? "收起素材槽位" : "检查/替换素材"}
|
||||
{isAttachmentSlotExpanded
|
||||
? isDirectReferenceUploadEnabled
|
||||
? "收起上传区"
|
||||
: "收起素材槽位"
|
||||
: isDirectReferenceUploadEnabled
|
||||
? "上传参考图"
|
||||
: "检查/替换素材"}
|
||||
{isAttachmentSlotExpanded ? (
|
||||
<ChevronUp className="ml-2 h-4 w-4" />
|
||||
) : (
|
||||
@ -4308,14 +4357,16 @@ export function AgentGenerationWorkspaceDarkV2({
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
{agentUploadSlots.length > 0 ? (
|
||||
{hasVisibleAttachmentUploadSlots ? (
|
||||
<CollapsibleContent className="mt-4 space-y-4">
|
||||
<div className="rounded-[20px] border border-emerald-400/15 bg-emerald-500/[0.06] px-4 py-3 text-xs leading-6 text-emerald-100/80">
|
||||
上一步已选的白底图和品牌模特图会自动带入对应槽位,这里只保留最终检查与单张上传替换,不再重复展示已选素材列表。
|
||||
{isDirectReferenceUploadEnabled
|
||||
? "当前模式不会展示前两步素材选择,上传到这里的图片会作为参考图直接参与本次模型生图。"
|
||||
: "上一步已选的白底图和品牌模特图会自动带入对应槽位,这里只保留最终检查与单张上传替换,不再重复展示已选素材列表。"}
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-2 gap-3 lg:grid-cols-4">
|
||||
{agentUploadSlots.map((slot, index) => {
|
||||
{visibleAttachmentUploadSlots.map((slot, index) => {
|
||||
return (
|
||||
<motion.div
|
||||
key={slot.label}
|
||||
@ -4596,7 +4647,10 @@ export function AgentGenerationWorkspaceDarkV2({
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
{hasAgentUploadSlots && isAttachmentSlotExpanded ? attachmentSlotPanel : null}
|
||||
{isDirectReferenceUploadEnabled ||
|
||||
(hasAgentUploadSlots && isAttachmentSlotExpanded)
|
||||
? attachmentSlotPanel
|
||||
: null}
|
||||
|
||||
<div className="rounded-[28px] border border-white/12 bg-white/[0.02] p-4">
|
||||
<h3 className="mb-3 flex items-center gap-2 text-sm font-semibold text-white">
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user