问题修复

This commit is contained in:
2025-09-20 00:38:35 +08:00
parent 480d8cce46
commit af2058f752
5 changed files with 397 additions and 33 deletions

View File

@@ -630,16 +630,76 @@ export const HistoryPanel: React.FC<{
};
img.onerror = (error) => {
console.error('图像加载失败:', error);
// 即使图像加载失败,也显示预览
setHoveredImage({
url: imageUrl,
title: `生成记录 G${globalIndex + 1}`,
width: 0,
height: 0
});
// 传递鼠标位置信息给App组件
if (setPreviewPosition) {
setPreviewPosition({ x: e.clientX, y: e.clientY });
// 如果是Blob URL失效尝试重新获取
if (imageUrl.startsWith('blob:')) {
import('../store/useAppStore').then((module) => {
const useAppStore = module.useAppStore;
const blob = useAppStore.getState().getBlob(imageUrl);
if (blob) {
console.log('从AppStore找到Blob尝试重新创建URL...');
// 重新创建Blob URL
const newUrl = URL.createObjectURL(blob);
// 更新显示
setHoveredImage({
url: newUrl,
title: `生成记录 G${globalIndex + 1}`,
width: 0,
height: 0
});
// 传递鼠标位置信息给App组件
if (setPreviewPosition) {
setPreviewPosition({ x: e.clientX, y: e.clientY });
}
// 预加载新URL
const newImg = new Image();
newImg.onload = () => {
setHoveredImage({
url: newUrl,
title: `生成记录 G${globalIndex + 1}`,
width: newImg.width,
height: newImg.height
});
};
newImg.src = newUrl;
} else {
// 即使图像加载失败,也显示预览
setHoveredImage({
url: imageUrl,
title: `生成记录 G${globalIndex + 1}`,
width: 0,
height: 0
});
// 传递鼠标位置信息给App组件
if (setPreviewPosition) {
setPreviewPosition({ x: e.clientX, y: e.clientY });
}
}
}).catch(err => {
console.error('导入AppStore时出错:', err);
// 即使图像加载失败,也显示预览
setHoveredImage({
url: imageUrl,
title: `生成记录 G${globalIndex + 1}`,
width: 0,
height: 0
});
// 传递鼠标位置信息给App组件
if (setPreviewPosition) {
setPreviewPosition({ x: e.clientX, y: e.clientY });
}
});
} else {
// 即使图像加载失败,也显示预览
setHoveredImage({
url: imageUrl,
title: `生成记录 G${globalIndex + 1}`,
width: 0,
height: 0
});
// 传递鼠标位置信息给App组件
if (setPreviewPosition) {
setPreviewPosition({ x: e.clientX, y: e.clientY });
}
}
};
img.src = imageUrl;
@@ -1026,7 +1086,30 @@ export const HistoryPanel: React.FC<{
? `${gen.uploadResults[index].url}?x-oss-process=image/quality,q_30`
: null;
const displayUrl = uploadedUrl || asset.url;
// 如果没有上传的URL则使用asset中的URL
const displayUrl = uploadedUrl || asset.url || asset.blobUrl;
// 如果URL是blob:开头但已失效,尝试重新创建
if (displayUrl && displayUrl.startsWith('blob:')) {
// 检查blob是否仍然有效
const img = new Image();
img.onerror = () => {
// Blob URL可能已失效尝试重新创建
import('../store/useAppStore').then((module) => {
const useAppStore = module.useAppStore;
const blob = useAppStore.getState().getBlob(displayUrl);
if (blob) {
const newUrl = URL.createObjectURL(blob);
// 更新显示
const imgElement = document.querySelector(`img[src="${displayUrl}"]`);
if (imgElement) {
imgElement.src = newUrl;
}
}
});
};
img.src = displayUrl;
}
return (
<div
@@ -1042,11 +1125,30 @@ export const HistoryPanel: React.FC<{
});
}}
>
<img
src={displayUrl}
alt={`生成结果 ${index + 1}`}
className="w-full h-full object-cover"
/>
{displayUrl ? (
<img
src={displayUrl}
alt={`生成结果 ${index + 1}`}
className="w-full h-full object-cover"
onError={(e) => {
// 如果图像加载失败尝试重新创建Blob URL
if (displayUrl.startsWith('blob:')) {
import('../store/useAppStore').then((module) => {
const useAppStore = module.useAppStore;
const blob = useAppStore.getState().getBlob(displayUrl);
if (blob) {
const newUrl = URL.createObjectURL(blob);
(e.target as HTMLImageElement).src = newUrl;
}
});
}
}}
/>
) : (
<div className="w-full h-full bg-gray-100 flex items-center justify-center">
<ImageIcon className="h-4 w-4 text-gray-400" />
</div>
)}
</div>
);
})}
@@ -1074,11 +1176,36 @@ export const HistoryPanel: React.FC<{
const fullGen = dbGenerations.find(item => item.id === gen.id) || gen;
const outputAssetsCount = fullGen.outputAssets?.length || 0;
const uploadedUrl = gen.uploadResults && gen.uploadResults[outputAssetsCount + index] && gen.uploadResults[outputAssetsCount + index].success
? `${gen.uploadResults[outputAssetsCount + index].url}?x-oss-process=image/quality,q_30`
// 确保索引在有效范围内
const uploadResultIndex = outputAssetsCount + index;
const uploadedUrl = fullGen.uploadResults && fullGen.uploadResults[uploadResultIndex] && fullGen.uploadResults[uploadResultIndex].success
? `${fullGen.uploadResults[uploadResultIndex].url}?x-oss-process=image/quality,q_30`
: null;
const displayUrl = uploadedUrl || asset.url;
// 如果没有上传的URL则使用asset中的URL
const displayUrl = uploadedUrl || asset.url || asset.blobUrl;
// 如果URL是blob:开头但已失效,尝试重新创建
if (displayUrl && displayUrl.startsWith('blob:')) {
// 检查blob是否仍然有效
const img = new Image();
img.onerror = () => {
// Blob URL可能已失效尝试重新创建
import('../store/useAppStore').then((module) => {
const useAppStore = module.useAppStore;
const blob = useAppStore.getState().getBlob(displayUrl);
if (blob) {
const newUrl = URL.createObjectURL(blob);
// 更新显示
const imgElement = document.querySelector(`img[src="${displayUrl}"]`);
if (imgElement) {
imgElement.src = newUrl;
}
}
});
};
img.src = displayUrl;
}
return (
<div
@@ -1094,11 +1221,30 @@ export const HistoryPanel: React.FC<{
});
}}
>
<img
src={displayUrl}
alt={`参考图像 ${index + 1}`}
className="w-full h-full object-cover"
/>
{displayUrl ? (
<img
src={displayUrl}
alt={`参考图像 ${index + 1}`}
className="w-full h-full object-cover"
onError={(e) => {
// 如果图像加载失败尝试重新创建Blob URL
if (displayUrl.startsWith('blob:')) {
import('../store/useAppStore').then((module) => {
const useAppStore = module.useAppStore;
const blob = useAppStore.getState().getBlob(displayUrl);
if (blob) {
const newUrl = URL.createObjectURL(blob);
(e.target as HTMLImageElement).src = newUrl;
}
});
}
}}
/>
) : (
<div className="w-full h-full bg-gray-100 flex items-center justify-center">
<ImageIcon className="h-4 w-4 text-gray-400" />
</div>
)}
</div>
);
})}
@@ -1166,6 +1312,95 @@ export const HistoryPanel: React.FC<{
</div>
)}
{/* 编辑结果图像 */}
{selectedEdit.outputAssets && selectedEdit.outputAssets.length > 0 && (
<div className="pt-2 border-t border-gray-200">
<h5 className="text-xs font-medium text-gray-500 mb-2"></h5>
<div className="text-xs text-gray-600 mb-2">
{selectedEdit.outputAssets.length}
</div>
<div className="flex flex-wrap gap-2">
{selectedEdit.outputAssets.slice(0, 4).map((asset: any, index: number) => {
// 获取上传后的远程链接(如果存在)
const uploadedUrl = selectedEdit.uploadResults && selectedEdit.uploadResults[index] && selectedEdit.uploadResults[index].success
? `${selectedEdit.uploadResults[index].url}?x-oss-process=image/quality,q_30`
: null;
// 如果没有上传的URL则使用asset中的URL
const displayUrl = uploadedUrl || asset.url || asset.blobUrl;
// 如果URL是blob:开头但已失效,尝试重新创建
if (displayUrl && displayUrl.startsWith('blob:')) {
// 检查blob是否仍然有效
const img = new Image();
img.onerror = () => {
// Blob URL可能已失效尝试重新创建
import('../store/useAppStore').then((module) => {
const useAppStore = module.useAppStore;
const blob = useAppStore.getState().getBlob(displayUrl);
if (blob) {
const newUrl = URL.createObjectURL(blob);
// 更新显示
const imgElement = document.querySelector(`img[src="${displayUrl}"]`);
if (imgElement) {
imgElement.src = newUrl;
}
}
});
};
img.src = displayUrl;
}
return (
<div
key={asset.id}
className="relative w-16 h-16 rounded border overflow-hidden cursor-pointer hover:ring-2 hover:ring-yellow-400"
onClick={(e) => {
e.stopPropagation();
setPreviewModal({
open: true,
imageUrl: displayUrl,
title: `编辑结果 ${index + 1}`,
description: `${asset.width} × ${asset.height}`
});
}}
>
{displayUrl ? (
<img
src={displayUrl}
alt={`编辑结果 ${index + 1}`}
className="w-full h-full object-cover"
onError={(e) => {
// 如果图像加载失败尝试重新创建Blob URL
if (displayUrl.startsWith('blob:')) {
import('../store/useAppStore').then((module) => {
const useAppStore = module.useAppStore;
const blob = useAppStore.getState().getBlob(displayUrl);
if (blob) {
const newUrl = URL.createObjectURL(blob);
(e.target as HTMLImageElement).src = newUrl;
}
});
}
}}
/>
) : (
<div className="w-full h-full bg-gray-100 flex items-center justify-center">
<ImageIcon className="h-4 w-4 text-gray-400" />
</div>
)}
</div>
);
})}
{selectedEdit.outputAssets.length > 4 && (
<div className="w-16 h-16 rounded border flex items-center justify-center bg-gray-100 text-xs text-gray-500">
+{selectedEdit.outputAssets.length - 4}
</div>
)}
</div>
</div>
)}
{/* 原始生成参考 */}
{parentGen && (
<div className="pt-2 border-t border-gray-200">
@@ -1184,10 +1419,37 @@ export const HistoryPanel: React.FC<{
// 获取上传后的远程链接(如果存在)
// 参考图像在uploadResults中从索引outputAssets.length开始
const outputAssetsCount = parentGen.outputAssets?.length || 0;
const uploadedUrl = parentGen.uploadResults && parentGen.uploadResults[outputAssetsCount + index] && parentGen.uploadResults[outputAssetsCount + index].success
? `${parentGen.uploadResults[outputAssetsCount + index].url}?x-oss-process=image/quality,q_30`
// 确保索引在有效范围内
const uploadResultIndex = outputAssetsCount + index;
const uploadedUrl = parentGen.uploadResults && parentGen.uploadResults[uploadResultIndex] && parentGen.uploadResults[uploadResultIndex].success
? `${parentGen.uploadResults[uploadResultIndex].url}?x-oss-process=image/quality,q_30`
: null;
const displayUrl = uploadedUrl || asset.url;
// 如果没有上传的URL则使用asset中的URL
const displayUrl = uploadedUrl || asset.url || asset.blobUrl;
// 如果URL是blob:开头但已失效,尝试重新创建
if (displayUrl && displayUrl.startsWith('blob:')) {
// 检查blob是否仍然有效
const img = new Image();
img.onerror = () => {
// Blob URL可能已失效尝试重新创建
import('../store/useAppStore').then((module) => {
const useAppStore = module.useAppStore;
const blob = useAppStore.getState().getBlob(displayUrl);
if (blob) {
const newUrl = URL.createObjectURL(blob);
// 更新显示
const imgElement = document.querySelector(`img[src="${displayUrl}"]`);
if (imgElement) {
imgElement.src = newUrl;
}
}
});
};
img.src = displayUrl;
}
return (
<div
@@ -1203,11 +1465,30 @@ export const HistoryPanel: React.FC<{
});
}}
>
<img
src={displayUrl}
alt={`原始参考图像 ${index + 1}`}
className="w-full h-full object-cover"
/>
{displayUrl ? (
<img
src={displayUrl}
alt={`原始参考图像 ${index + 1}`}
className="w-full h-full object-cover"
onError={(e) => {
// 如果图像加载失败尝试重新创建Blob URL
if (displayUrl.startsWith('blob:')) {
import('../store/useAppStore').then((module) => {
const useAppStore = module.useAppStore;
const blob = useAppStore.getState().getBlob(displayUrl);
if (blob) {
const newUrl = URL.createObjectURL(blob);
(e.target as HTMLImageElement).src = newUrl;
}
});
}
}}
/>
) : (
<div className="w-full h-full bg-gray-100 flex items-center justify-center">
<ImageIcon className="h-4 w-4 text-gray-400" />
</div>
)}
</div>
);
})}