feat: 实现AI穿搭方案智能分组功能
- 修改提示词让AI直接返回分组结构 - 添加GroupingStrategy和OutfitQualityScore数据结构 - 支持按风格、场合、季节等维度智能分组 - 为每个方案添加质量评分系统 - 前端支持分组展示和获取更多同类方案 - 保持向后兼容性 主要变更: - 后端: 更新提示词和解析逻辑支持分组JSON结构 - 前端: OutfitRecommendationList支持分组显示 - 类型: 新增分组相关TypeScript接口 - 功能: 每个分组支持'获取更多'按钮扩展方案
This commit is contained in:
@@ -10,7 +10,14 @@ import {
|
||||
Info
|
||||
} from 'lucide-react';
|
||||
import OutfitRecommendationService from '../../services/outfitRecommendationService';
|
||||
import { OutfitRecommendation, STYLE_OPTIONS, OCCASION_OPTIONS, SEASON_OPTIONS } from '../../types/outfitRecommendation';
|
||||
import {
|
||||
OutfitRecommendation,
|
||||
OutfitRecommendationGroup,
|
||||
GroupingStrategy,
|
||||
STYLE_OPTIONS,
|
||||
OCCASION_OPTIONS,
|
||||
SEASON_OPTIONS
|
||||
} from '../../types/outfitRecommendation';
|
||||
import OutfitRecommendationList from '../../components/outfit/OutfitRecommendationList';
|
||||
import { CustomSelect } from '../../components/CustomSelect';
|
||||
import { MaterialSearchPanel, MaterialDetailModal } from '../../components/material';
|
||||
@@ -28,6 +35,9 @@ const OutfitRecommendationTool: React.FC = () => {
|
||||
const [colorPreferences, setColorPreferences] = useState<string[]>([]);
|
||||
const [count, setCount] = useState(3);
|
||||
|
||||
// 分组相关状态
|
||||
const [groups, setGroups] = useState<OutfitRecommendationGroup[]>([]);
|
||||
const [groupingStrategy, setGroupingStrategy] = useState<GroupingStrategy | null>(null);
|
||||
const [recommendations, setRecommendations] = useState<OutfitRecommendation[]>([]);
|
||||
const [isGenerating, setIsGenerating] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
@@ -61,7 +71,18 @@ const OutfitRecommendationTool: React.FC = () => {
|
||||
count,
|
||||
});
|
||||
|
||||
setRecommendations(response.recommendations);
|
||||
// 更新分组和方案数据
|
||||
if (response.groups && response.groups.length > 0) {
|
||||
setGroups(response.groups);
|
||||
setGroupingStrategy(response.grouping_strategy);
|
||||
// 为向后兼容,也设置recommendations
|
||||
setRecommendations(response.recommendations || []);
|
||||
} else {
|
||||
// 向后兼容模式
|
||||
setGroups([]);
|
||||
setGroupingStrategy(null);
|
||||
setRecommendations(response.recommendations || []);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('穿搭方案生成失败:', err);
|
||||
setError(err instanceof Error ? err.message : '穿搭方案生成失败');
|
||||
@@ -75,6 +96,65 @@ const OutfitRecommendationTool: React.FC = () => {
|
||||
handleGenerate();
|
||||
}, [handleGenerate]);
|
||||
|
||||
// 获取更多同类方案
|
||||
const handleLoadMoreForGroup = useCallback(async (groupId: string, styleKeywords: string[]) => {
|
||||
try {
|
||||
console.log(`🎨 获取分组 ${groupId} 的更多方案,关键词:`, styleKeywords);
|
||||
|
||||
// 构建增强的查询
|
||||
const enhancedQuery = `${query} ${styleKeywords.join(' ')}`;
|
||||
|
||||
const response = await OutfitRecommendationService.generateRecommendations({
|
||||
query: enhancedQuery,
|
||||
target_style: targetStyle || undefined,
|
||||
occasions: occasions.length > 0 ? occasions : undefined,
|
||||
season: season || undefined,
|
||||
color_preferences: colorPreferences.length > 0 ? colorPreferences : undefined,
|
||||
count: 3, // 每次获取3个新方案
|
||||
});
|
||||
|
||||
// 找到对应的分组并添加新方案
|
||||
if (response.groups && response.groups.length > 0) {
|
||||
// 如果返回了分组,合并到现有分组中
|
||||
setGroups(prevGroups => {
|
||||
return prevGroups.map(group => {
|
||||
if (group.group_id === groupId) {
|
||||
// 找到匹配的新分组并合并方案
|
||||
const newGroup = response.groups.find(g =>
|
||||
g.style_keywords.some(keyword =>
|
||||
styleKeywords.includes(keyword)
|
||||
)
|
||||
);
|
||||
if (newGroup) {
|
||||
return {
|
||||
...group,
|
||||
children: [...group.children, ...newGroup.children]
|
||||
};
|
||||
}
|
||||
}
|
||||
return group;
|
||||
});
|
||||
});
|
||||
} else if (response.recommendations) {
|
||||
// 向后兼容:直接添加到对应分组
|
||||
setGroups(prevGroups => {
|
||||
return prevGroups.map(group => {
|
||||
if (group.group_id === groupId) {
|
||||
return {
|
||||
...group,
|
||||
children: [...group.children, ...response.recommendations]
|
||||
};
|
||||
}
|
||||
return group;
|
||||
});
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取更多方案失败:', err);
|
||||
setError(err instanceof Error ? err.message : '获取更多方案失败');
|
||||
}
|
||||
}, [query, targetStyle, occasions, season, colorPreferences]);
|
||||
|
||||
// 清空表单
|
||||
const handleClear = useCallback(() => {
|
||||
setQuery('');
|
||||
@@ -83,6 +163,8 @@ const OutfitRecommendationTool: React.FC = () => {
|
||||
setSeason('');
|
||||
setColorPreferences([]);
|
||||
setCount(3);
|
||||
setGroups([]);
|
||||
setGroupingStrategy(null);
|
||||
setRecommendations([]);
|
||||
setError(null);
|
||||
}, []);
|
||||
@@ -362,11 +444,14 @@ const OutfitRecommendationTool: React.FC = () => {
|
||||
{/* 右侧结果区域 */}
|
||||
<div className="lg:col-span-3">
|
||||
<OutfitRecommendationList
|
||||
groups={groups}
|
||||
groupingStrategy={groupingStrategy || undefined}
|
||||
recommendations={recommendations}
|
||||
isLoading={isGenerating}
|
||||
error={error || undefined}
|
||||
onRegenerate={handleRegenerate}
|
||||
onMaterialSearch={handleMaterialSearch}
|
||||
onLoadMoreForGroup={handleLoadMoreForGroup}
|
||||
className="min-h-[600px]"
|
||||
/>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user