diff --git a/components/canvas/CanvasChatPanel.tsx b/components/canvas/CanvasChatPanel.tsx index fa90e1c8f..4c285c012 100644 --- a/components/canvas/CanvasChatPanel.tsx +++ b/components/canvas/CanvasChatPanel.tsx @@ -1372,6 +1372,65 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF useEffect(() => { if (pendingChatAttachments.length === 0) return; + if (isDetailGenerationMode) { + const normalized = pendingChatAttachments + .filter((item) => item?.url) + .map((item) => ({ + url: item.url, + name: item.name || "素材图", + contentType: item.contentType || "image/jpeg", + })) as PickedObjectAttachment[]; + + if (normalized.length > 0) { + let inserted = 0; + const targetSlotIndex = detailSlotPickerIndex; + + setDetailSlots((current) => { + const next = [...current]; + + const allIndexes = DETAIL_SLOT_CONFIGS.map((_, index) => index); + let priorityIndexes = allIndexes; + + if (targetSlotIndex !== null && targetSlotIndex >= 0 && targetSlotIndex < DETAIL_SLOT_CONFIGS.length) { + const role = DETAIL_SLOT_CONFIGS[targetSlotIndex]?.role; + const sameRoleIndexes = DETAIL_SLOT_CONFIGS.map((slot, index) => + slot.role === role ? index : -1 + ).filter((index) => index >= 0); + const sameRoleStart = sameRoleIndexes.indexOf(targetSlotIndex); + const orderedSameRole = + sameRoleStart >= 0 ? sameRoleIndexes.slice(sameRoleStart) : sameRoleIndexes; + priorityIndexes = [targetSlotIndex, ...orderedSameRole.filter((index) => index !== targetSlotIndex)]; + } + + let cursor = 0; + for (let i = 0; i < priorityIndexes.length && cursor < normalized.length; i += 1) { + const slotIdx = priorityIndexes[i]!; + const canReplaceActive = targetSlotIndex !== null && slotIdx === targetSlotIndex && cursor === 0; + if (!canReplaceActive && next[slotIdx]) continue; + next[slotIdx] = normalized[cursor]!; + cursor += 1; + inserted += 1; + } + + return next; + }); + + if (inserted > 0) { + toast.success( + inserted > 1 ? `已添加 ${inserted} 张到 AI详情素材槽位` : "已添加到 AI详情素材槽位" + ); + if (targetSlotIndex !== null) { + setDetailSlotPickerIndex(null); + } + } else { + toast.info("详情素材槽位已满,请先替换或清空后再添加"); + } + } + + clearPendingChatAttachments(); + return; + } + if (isVideoModel && videoFrameSlots.length > 0) { const slotCount = videoFrameSlots.length; const currentSlots: Array = Array.from( @@ -1437,6 +1496,8 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF clearPendingChatAttachments(); }, [ pendingChatAttachments, + isDetailGenerationMode, + detailSlotPickerIndex, isVideoModel, videoFrameSlots.length, attachments,