refactor: 简化穿搭图片生成弹框,移除风格偏好和生成记录功能

- 移除OutfitImageGenerator中的风格偏好标签功能
  - 删除stylePreferences状态和相关函数
  - 移除风格偏好UI界面和预设按钮
  - 更新使用说明,去掉风格偏好描述
- 简化OutfitImageGenerationModal组件
  - 移除穿搭图片生成记录显示功能
  - 删除OutfitImageGallery组件使用
  - 移除底部操作栏和记录相关参数
  - 改为单列居中布局,专注生成功能
- 清理ModelDetail页面中不再使用的代码
  - 移除outfitRecordsLoading状态
  - 删除handleDeleteOutfitRecord函数
  - 简化loadOutfitRecords函数
- 优化用户体验,界面更加简洁清爽
This commit is contained in:
imeepos 2025-07-30 15:22:13 +08:00
parent 26353f49a7
commit 44486e5df7
3 changed files with 17 additions and 126 deletions

View File

@ -2,20 +2,15 @@ import React, { useEffect } from 'react';
import { createPortal } from 'react-dom';
import { X, Sparkles } from 'lucide-react';
import { Model } from '../types/model';
import { OutfitImageRecord, OutfitImageGenerationRequest } from '../types/outfitImage';
import { OutfitImageGenerationRequest } from '../types/outfitImage';
import { OutfitImageGenerator } from './OutfitImageGenerator';
import { OutfitImageGallery } from './OutfitImageGallery';
interface OutfitImageGenerationModalProps {
isOpen: boolean;
onClose: () => void;
model: Model;
outfitRecords: OutfitImageRecord[];
onGenerate: (request: OutfitImageGenerationRequest) => Promise<void>;
onDeleteRecord: (record: OutfitImageRecord) => Promise<void>;
onRefreshRecords: () => Promise<void>;
isGenerating?: boolean;
recordsLoading?: boolean;
}
/**
@ -26,12 +21,8 @@ export const OutfitImageGenerationModal: React.FC<OutfitImageGenerationModalProp
isOpen,
onClose,
model,
outfitRecords,
onGenerate,
onDeleteRecord,
onRefreshRecords,
isGenerating = false,
recordsLoading = false
isGenerating = false
}) => {
// 键盘事件处理
useEffect(() => {
@ -93,9 +84,8 @@ export const OutfitImageGenerationModal: React.FC<OutfitImageGenerationModalProp
{/* 主要内容区域 */}
<div className="flex-1 overflow-y-auto p-6">
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6 h-full">
<div className="max-w-2xl mx-auto">
{/* 穿搭图片生成器 */}
<div className="space-y-6">
<OutfitImageGenerator
modelId={model.id}
modelPhotos={model.photos}
@ -103,40 +93,9 @@ export const OutfitImageGenerationModal: React.FC<OutfitImageGenerationModalProp
isGenerating={isGenerating}
/>
</div>
{/* 穿搭图片生成记录 */}
<div className="space-y-6">
<OutfitImageGallery
records={outfitRecords}
onDelete={onDeleteRecord}
onRefresh={onRefreshRecords}
loading={recordsLoading}
/>
</div>
</div>
</div>
{/* 底部操作栏(可选) */}
<div className="flex items-center justify-between p-6 border-t border-gray-200 bg-gray-50">
<div className="text-sm text-gray-500">
{outfitRecords.length}
</div>
<div className="flex items-center space-x-3">
<button
onClick={onRefreshRecords}
className="px-4 py-2 text-gray-600 hover:text-gray-800 hover:bg-gray-200 rounded-lg transition-colors text-sm"
>
</button>
<button
onClick={onClose}
className="px-6 py-2 bg-gray-600 text-white rounded-lg hover:bg-gray-700 transition-colors text-sm"
>
</button>
</div>
</div>
</div>
</div>,
modalRoot

View File

@ -7,8 +7,7 @@ import {
AlertCircle,
Image as ImageIcon,
Wand2,
Settings,
Plus
Settings
} from 'lucide-react';
import { ModelPhoto, PhotoType } from '../types/model';
import { OutfitImageGenerationRequest } from '../types/outfitImage';
@ -38,7 +37,6 @@ export const OutfitImageGenerator: React.FC<OutfitImageGeneratorProps> = ({
const [selectedModelImageId, setSelectedModelImageId] = useState<string>('');
const [productImages, setProductImages] = useState<string[]>([]);
const [generationPrompt, setGenerationPrompt] = useState('');
const [stylePreferences, setStylePreferences] = useState<string[]>([]);
const [error, setError] = useState<string | null>(null);
const [dragOver, setDragOver] = useState(false);
@ -125,17 +123,7 @@ export const OutfitImageGenerator: React.FC<OutfitImageGeneratorProps> = ({
setProductImages(prev => prev.filter((_, i) => i !== index));
}, []);
// 添加风格偏好
const addStylePreference = useCallback((style: string) => {
if (style.trim() && !stylePreferences.includes(style.trim())) {
setStylePreferences(prev => [...prev, style.trim()]);
}
}, [stylePreferences]);
// 移除风格偏好
const removeStylePreference = useCallback((index: number) => {
setStylePreferences(prev => prev.filter((_, i) => i !== index));
}, []);
// 处理生成请求
const handleGenerate = useCallback(async () => {
@ -157,7 +145,7 @@ export const OutfitImageGenerator: React.FC<OutfitImageGeneratorProps> = ({
model_image_id: selectedModelImageId,
product_image_paths: productImages,
generation_prompt: generationPrompt || undefined,
style_preferences: stylePreferences.length > 0 ? stylePreferences : undefined
style_preferences: undefined
};
await onGenerate(request);
@ -166,12 +154,11 @@ export const OutfitImageGenerator: React.FC<OutfitImageGeneratorProps> = ({
setSelectedModelImageId('');
setProductImages([]);
setGenerationPrompt('');
setStylePreferences([]);
} catch (error) {
console.error('生成穿搭图片失败:', error);
setError(`生成穿搭图片失败: ${error}`);
}
}, [modelId, selectedModelImageId, productImages, generationPrompt, stylePreferences, onGenerate]);
}, [modelId, selectedModelImageId, productImages, generationPrompt, onGenerate]);
const canGenerate = selectedModelImageId && productImages.length > 0 && !isGenerating && !disabled;
@ -323,43 +310,7 @@ export const OutfitImageGenerator: React.FC<OutfitImageGeneratorProps> = ({
/>
</div>
{/* 风格偏好 */}
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
</label>
<div className="flex flex-wrap gap-2 mb-2">
{stylePreferences.map((style, index) => (
<span
key={index}
className="inline-flex items-center px-3 py-1 bg-purple-100 text-purple-800 text-sm rounded-full"
>
{style}
<button
onClick={() => removeStylePreference(index)}
className="ml-2 text-purple-600 hover:text-purple-800"
disabled={disabled || isGenerating}
>
<X className="w-3 h-3" />
</button>
</span>
))}
</div>
<div className="flex space-x-2">
{['时尚', '休闲', '商务', '运动', '甜美', '酷炫'].map((style) => (
<button
key={style}
onClick={() => addStylePreference(style)}
className="px-3 py-1 text-sm border border-gray-300 rounded-full hover:bg-gray-50 transition-colors"
disabled={disabled || isGenerating || stylePreferences.includes(style)}
>
<Plus className="w-3 h-3 inline mr-1" />
{style}
</button>
))}
</div>
</div>
</div>
{/* 错误提示 */}
@ -410,7 +361,7 @@ export const OutfitImageGenerator: React.FC<OutfitImageGeneratorProps> = ({
<ul className="space-y-1 text-xs">
<li> </li>
<li> </li>
<li> </li>
<li> AI生成</li>
<li> AI将为您创建穿搭效果图</li>
<li> </li>
</ul>

View File

@ -44,7 +44,7 @@ const ModelDetail: React.FC = () => {
const [dashboardStats, setDashboardStats] = useState<ModelDashboardStats | null>(null);
const [statsLoading, setStatsLoading] = useState(false);
const [outfitRecords, setOutfitRecords] = useState<OutfitImageRecord[]>([]);
const [outfitRecordsLoading, setOutfitRecordsLoading] = useState(false);
const [generatingOutfit, setGeneratingOutfit] = useState(false);
const [activeTab, setActiveTab] = useState<TabId>('overview');
const [dynamics] = useState<ModelDynamic[]>([]);
@ -169,13 +169,10 @@ const ModelDetail: React.FC = () => {
if (!id) return;
try {
setOutfitRecordsLoading(true);
const records = await OutfitImageService.getOutfitImageRecords(id);
setOutfitRecords(records);
} catch (err) {
console.error('加载穿搭图片记录失败:', err);
} finally {
setOutfitRecordsLoading(false);
}
};
@ -196,19 +193,7 @@ const ModelDetail: React.FC = () => {
}
};
// 删除穿搭图片记录
const handleDeleteOutfitRecord = async (record: OutfitImageRecord) => {
try {
await OutfitImageService.deleteOutfitImageRecord(record.id);
// 重新加载记录和统计信息
await loadOutfitRecords();
await loadDashboardStats();
} catch (err) {
console.error('删除穿搭图片记录失败:', err);
setError(err as string);
}
};
// 上传照片
const handleUploadPhotos = async () => {
@ -563,12 +548,8 @@ const ModelDetail: React.FC = () => {
isOpen={showOutfitModal}
onClose={() => setShowOutfitModal(false)}
model={model}
outfitRecords={outfitRecords}
onGenerate={handleGenerateOutfitImages}
onDeleteRecord={handleDeleteOutfitRecord}
onRefreshRecords={loadOutfitRecords}
isGenerating={generatingOutfit}
recordsLoading={outfitRecordsLoading}
/>
)}
</div>