From d7411de33d911fc50da9545a78a71ebff6d1a321 Mon Sep 17 00:00:00 2001 From: imeepos Date: Fri, 25 Jul 2025 17:42:43 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E6=9D=83=E9=87=8D?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E9=A2=84=E8=A7=88=E6=98=BE=E7=A4=BA=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E5=88=86=E7=B1=BB=E6=95=B0=E9=87=8F=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修改 WeightPreviewTooltip 组件,只显示实际选中的分类权重 - 对于非按顺序匹配规则,不显示权重预览信息 - 确保权重指示器和预览提示都显示正确的分类数量 - 解决选择2个分类却显示4个分类的问题 --- FEATURE_DEMO.md | 165 ++++++++++++++++++ .../template/SegmentWeightIndicator.tsx | 50 +++--- .../template/TemplateDetailModal.tsx | 1 + 3 files changed, 194 insertions(+), 22 deletions(-) create mode 100644 FEATURE_DEMO.md diff --git a/FEATURE_DEMO.md b/FEATURE_DEMO.md new file mode 100644 index 0000000..1dfe5b7 --- /dev/null +++ b/FEATURE_DEMO.md @@ -0,0 +1,165 @@ +# 按顺序匹配规则权重配置功能演示 + +## 功能概述 + +现在当用户选择"按顺序匹配"规则类型时,可以在同一个编辑界面中直接调整权重,而不需要保存后再在外面单独调整。这大大改善了用户体验。 + +## 主要改进 + +### 1. 实时权重编辑 +- **之前**: 需要先保存匹配规则,然后在外部单独编辑权重 +- **现在**: 选中分类后,右侧权重立即变为可编辑的输入框 + +### 2. 精确保存机制 +- **保存逻辑**: 只保存选中分类的权重,自动删除未选中分类的权重记录 +- **数据一致性**: 确保权重配置与分类选择完全同步 + +### 3. 简化的用户界面 +- **集成设计**: 分类选择和权重编辑在同一行完成 +- **即时反馈**: 选中/取消选中分类时,权重编辑状态立即切换 +- **清晰布局**: 移除重复的权重配置区域,界面更简洁 + +## 使用流程 + +### 步骤 1: 选择匹配规则 +1. 在模板详情页面,展开轨道片段 +2. 点击"编辑"按钮进入匹配规则编辑模式 +3. 在规则类型下拉框中选择"按顺序匹配" + +### 步骤 2: 选择AI分类 +1. 在"按权重顺序匹配的分类"区域选择需要的AI分类 +2. 可以选择多个分类,系统会按权重顺序尝试匹配 + +### 步骤 3: 配置权重(新功能) +1. 选择分类后,下方会自动显示"权重配置"区域 +2. 每个选中的分类都有独立的权重调整控件 +3. 使用滑块或数字输入框调整权重值(0-100) +4. 实时查看权重等级和排序 + +### 步骤 4: 保存配置 +1. 点击"保存"按钮 +2. 系统会同时保存匹配规则和权重配置 +3. 无需额外的权重配置步骤 + +## 技术实现 + +### 前端组件修改 +- `SegmentMatchingRuleEditor.tsx`: 集成权重编辑功能 +- `TemplateDetailModal.tsx`: 优化权重相关功能的显示逻辑 + +### 核心功能 +1. **权重数据加载**: 在编辑"按顺序匹配"规则时自动加载权重数据 +2. **实时权重调整**: 支持滑块和数字输入的实时权重修改 +3. **统一保存**: 保存匹配规则时同时保存权重配置 +4. **智能显示**: 根据规则类型智能显示/隐藏权重相关功能 + +### 用户体验优化 +- **一体化操作**: 规则配置和权重设置在同一界面完成 +- **即时反馈**: 权重调整后立即显示等级和排序变化 +- **清晰指引**: 提供操作说明和提示信息 +- **响应式设计**: 适配不同屏幕尺寸 + +## 代码示例 + +### 权重编辑界面结构 +```tsx +{/* 权重配置区域 - 只在有模板ID且选择了分类时显示 */} +{templateId && SegmentMatchingRuleHelper.isPriorityOrder(editingRule) && ( +
+ + + {/* 权重调整控件 */} + {selectedClassifications.map((classification) => ( +
+ {/* 滑块控制 */} + handleWeightChange(classification.id, parseInt(e.target.value))} + /> + + {/* 数字输入 */} + handleWeightChange(classification.id, parseInt(e.target.value))} + /> +
+ ))} +
+)} +``` + +### 保存逻辑 +```tsx +const handleSaveRule = async () => { + // 保存匹配规则 + await updateSegmentMatchingRule(segmentId, editingRule); + + // 如果是按顺序匹配规则,同时保存权重配置 + if (SegmentMatchingRuleHelper.isPriorityOrder(editingRule) && templateId) { + await TemplateSegmentWeightService.setSegmentWeights( + templateId, + segmentId, + editingWeights + ); + } +}; +``` + +## 测试建议 + +1. **功能测试**: + - 验证只有"按顺序匹配"规则显示权重配置 + - 测试权重调整的实时响应 + - 确认保存后权重配置正确应用 + +2. **用户体验测试**: + - 测试界面的直观性和易用性 + - 验证操作流程的流畅性 + - 检查不同屏幕尺寸的适配 + +3. **边界情况测试**: + - 测试权重值边界(0-100) + - 验证无AI分类时的处理 + - 测试网络错误时的降级处理 + +## 问题修复 + +### 权重指示器分类数量显示错误 + +**问题描述**: +用户选择了2个分类(全身/上半身)并设置权重后,前端显示"自定义 (平均: 8.5)最高: 10•4 分类",但实际只选择了2个分类。 + +**问题原因**: +`SegmentWeightIndicator` 组件使用 `getSegmentWeightsWithDefaults` 方法获取权重数据,该方法返回所有激活AI分类的权重(包括默认值),而不是只返回用户实际选择的分类。 + +**解决方案**: +1. 在 `SegmentWeightIndicator` 组件中添加 `segmentMatchingRule` 参数 +2. 根据匹配规则类型智能统计分类数量: + - 对于"按顺序匹配"规则:只统计用户选择的分类 + - 对于其他规则类型:使用所有权重数据 +3. 修改权重统计逻辑,过滤出实际相关的分类权重 + +**修复效果**: +- ✅ 现在显示准确的分类数量(如:2 分类) +- ✅ 权重统计只基于实际选择的分类 +- ✅ 平均权重和最高权重计算更准确 + +## 总结 + +这个功能改进显著提升了用户体验,将原本需要多步操作的权重配置集成到匹配规则编辑的单一界面中。用户现在可以: + +- ✅ 在一个界面完成规则和权重配置 +- ✅ 实时预览权重调整效果 +- ✅ 享受更流畅的操作体验 +- ✅ 减少操作步骤和学习成本 +- ✅ 看到准确的分类数量和权重统计 + +这种设计符合现代UI/UX的最佳实践,提供了更加直观和高效的用户交互体验。 diff --git a/apps/desktop/src/components/template/SegmentWeightIndicator.tsx b/apps/desktop/src/components/template/SegmentWeightIndicator.tsx index a8099d0..9975ab4 100644 --- a/apps/desktop/src/components/template/SegmentWeightIndicator.tsx +++ b/apps/desktop/src/components/template/SegmentWeightIndicator.tsx @@ -59,38 +59,21 @@ export const SegmentWeightIndicator: React.FC = ({ // 计算权重摘要 - 只统计实际选择的分类 let relevantWeights: Record = {}; - console.log('SegmentWeightIndicator Debug:', { - segmentMatchingRule, - isPriorityOrder: segmentMatchingRule ? SegmentMatchingRuleHelper.isPriorityOrder(segmentMatchingRule) : false, - allWeights: weights, - allWeightsCount: Object.keys(weights).length - }); - if (segmentMatchingRule && SegmentMatchingRuleHelper.isPriorityOrder(segmentMatchingRule)) { // 对于按顺序匹配规则,只统计选择的分类 const selectedCategoryIds = typeof segmentMatchingRule === 'object' && 'PriorityOrder' in segmentMatchingRule ? segmentMatchingRule.PriorityOrder.category_ids : []; - console.log('PriorityOrder Debug:', { - selectedCategoryIds, - selectedCount: selectedCategoryIds.length - }); - // 只包含选择的分类的权重 relevantWeights = Object.fromEntries( Object.entries(weights).filter(([classificationId]) => selectedCategoryIds.includes(classificationId) ) ); - - console.log('Filtered weights:', { - relevantWeights, - relevantCount: Object.keys(relevantWeights).length - }); } else { - // 对于其他规则类型,使用所有权重 - relevantWeights = weights; + // 对于其他规则类型,不显示权重信息(因为不相关) + relevantWeights = {}; } const weightValues = Object.values(relevantWeights); @@ -221,12 +204,14 @@ export const SegmentWeightIndicator: React.FC = ({ interface WeightPreviewTooltipProps { templateId: string; trackSegmentId: string; + segmentMatchingRule?: any; // 添加匹配规则参数 children: React.ReactNode; } export const WeightPreviewTooltip: React.FC = ({ templateId, trackSegmentId, + segmentMatchingRule, children, }) => { const [showTooltip, setShowTooltip] = useState(false); @@ -235,14 +220,35 @@ export const WeightPreviewTooltip: React.FC = ({ const loadWeights = async () => { if (loading) return; - + try { setLoading(true); - const weightData = await TemplateSegmentWeightService.getSegmentWeightsWithDefaults( + const allWeights = await TemplateSegmentWeightService.getSegmentWeightsWithDefaults( templateId, trackSegmentId ); - setWeights(weightData); + + // 过滤权重数据,只显示实际选中的分类 + let relevantWeights: Record = {}; + + if (segmentMatchingRule && SegmentMatchingRuleHelper.isPriorityOrder(segmentMatchingRule)) { + // 对于按顺序匹配规则,只显示选择的分类 + const selectedCategoryIds = typeof segmentMatchingRule === 'object' && 'PriorityOrder' in segmentMatchingRule + ? segmentMatchingRule.PriorityOrder.category_ids + : []; + + // 只包含选择的分类的权重 + relevantWeights = Object.fromEntries( + Object.entries(allWeights).filter(([classificationId]) => + selectedCategoryIds.includes(classificationId) + ) + ); + } else { + // 对于其他规则类型,不显示权重信息 + relevantWeights = {}; + } + + setWeights(relevantWeights); } catch (error) { console.error('加载权重预览失败:', error); } finally { diff --git a/apps/desktop/src/components/template/TemplateDetailModal.tsx b/apps/desktop/src/components/template/TemplateDetailModal.tsx index ae58cee..8f94091 100644 --- a/apps/desktop/src/components/template/TemplateDetailModal.tsx +++ b/apps/desktop/src/components/template/TemplateDetailModal.tsx @@ -791,6 +791,7 @@ export const TemplateDetailModal: React.FC = ({