# 业务融合功能重构 - 实施方案

## 📋 需要添加的功能

### 1. 数据结构更新 ✅ 已完成
- [x] 添加 `source` 字段（auto/manual）
- [x] 添加 `executionMode` 字段（manual/auto）
- [x] 添加 `autoTriggerConditions` 字段
- [x] 添加 `targetDevices` 字段
- [x] 添加 `createdBy` 字段（手动添加时）

### 2. UI布局调整

#### 2.1 标题栏添加"手动添加决策"按钮
```tsx
<Card className="p-6 bg-gradient-to-r from-purple-50 to-blue-50 border-purple-200">
  <div className="flex items-start gap-3">
    <Merge className="w-6 h-6 text-purple-600 flex-shrink-0 mt-1" />
    <div className="flex-1">
      <div className="flex items-center justify-between mb-2">
        <h2>业务融合功能</h2>
        <Button onClick={() => setShowAddDecisionDialog(true)} className="bg-green-600 hover:bg-green-700">
          <Plus className="w-4 h-4 mr-2" />
          手动添加决策
        </Button>
      </div>
      <p className="text-sm text-muted-foreground mb-3">
        自动生成和手动添加决策，支持手动执行或自动执行（达到环境条件时自动控制物联网设备）
      </p>
      ...
    </div>
  </div>
</Card>
```

#### 2.2 添加分类Tab
```tsx
<Card className="p-6">
  <Tabs value={activeTab} onValueChange={(v) => setActiveTab(v as 'all' | 'auto' | 'manual')}>
    <div className="flex items-center justify-between mb-4">
      <TabsList>
        <TabsTrigger value="all">全部决策</TabsTrigger>
        <TabsTrigger value="auto">自动生成</TabsTrigger>
        <TabsTrigger value="manual">手动添加</TabsTrigger>
      </TabsList>
      <p className="text-sm text-muted-foreground">
        共 {filteredDecisions.length} 条决策
      </p>
    </div>
  </Tabs>
</Card>
```

#### 2.3 决策卡片显示来源和执行模式
```tsx
<Card key={result.id} className="p-6 hover:shadow-lg transition-shadow">
  <div className="flex items-start justify-between mb-4">
    <div className="flex-1">
      <div className="flex items-center gap-2 mb-2">
        <h4>{result.name}</h4>
        {getDecisionLevelBadge(result.level)}
        
        {/* 来源标识 */}
        {result.source === 'auto' ? (
          <Badge variant="outline" className="bg-purple-50 text-purple-700">
            <Brain className="w-3 h-3 mr-1" />
            自动生成
          </Badge>
        ) : (
          <Badge variant="outline" className="bg-blue-50 text-blue-700">
            <Edit className="w-3 h-3 mr-1" />
            手动添加
          </Badge>
        )}
        
        {/* 执行模式标识 */}
        {result.executionMode === 'auto' ? (
          <Badge variant="outline" className="bg-green-50 text-green-700">
            <Zap className="w-3 h-3 mr-1" />
            自动执行
          </Badge>
        ) : (
          <Badge variant="outline" className="bg-gray-50 text-gray-700">
            <Play className="w-3 h-3 mr-1" />
            手动执行
          </Badge>
        )}
        
        <div className="flex items-center gap-1 text-sm">
          <Gauge className="w-4 h-4 text-green-600" />
          <span className="font-medium">{(result.confidence * 100).toFixed(0)}%</span>
        </div>
      </div>
      
      <div className="text-sm mb-3">{result.recommendation}</div>
      
      {/* 自动执行时显示触发条件 */}
      {result.executionMode === 'auto' && result.autoTriggerConditions && (
        <div className="flex items-center gap-2 mb-2 text-xs">
          <Settings className="w-3 h-3 text-gray-500" />
          <span className="text-muted-foreground">
            触发条件: {result.autoTriggerConditions.conditions.map(c => 
              `${c.field}${c.operator}${c.value}`
            ).join(' AND ')}
          </span>
        </div>
      )}
      
      {/* 目标设备 */}
      {result.targetDevices && result.targetDevices.length > 0 && (
        <div className="flex items-center gap-2 mb-2 text-xs">
          <Activity className="w-3 h-3 text-gray-500" />
          <span className="text-muted-foreground">
            目标设备: {result.targetDevices.join(', ')}
          </span>
        </div>
      )}
      
      <div className="flex items-center gap-4 text-xs text-muted-foreground">
        <div className="flex items-center gap-1">
          <Clock className="w-3 h-3" />
          {result.generatedAt}
        </div>
        {result.createdBy && (
          <div className="flex items-center gap-1">
            <User className="w-3 h-3" />
            创建人: {result.createdBy}
          </div>
        )}
        <div className="flex items-center gap-1">
          <ListChecks className="w-3 h-3" />
          {result.actionItems.length} 个执行步骤
        </div>
      </div>
    </div>
    
    <div className="flex gap-2">
      <Button
        size="sm"
        variant="outline"
        onClick={() => handleEditDecision(result)}
      >
        <Edit className="w-4 h-4 mr-2" />
        编辑
      </Button>
      <Button
        size="sm"
        onClick={() => handleExecuteDecision(result)}
        className="bg-green-600 hover:bg-green-700"
      >
        <Play className="w-4 h-4 mr-2" />
        执行
      </Button>
      <Button
        size="sm"
        variant="outline"
        onClick={() => handleViewResult(result)}
      >
        <Eye className="w-4 h-4 mr-2" />
        查看详情
      </Button>
    </div>
  </div>
  
  {/* 只有自动生成的决策才显示融合过程 */}
  {result.source === 'auto' && (
    <div className="pt-4 border-t">
      <div className="text-sm text-muted-foreground mb-2">融合过程:</div>
      <div className="flex items-center gap-2 overflow-x-auto pb-2">
        {result.fusionProcess.map((process, idx) => (
          <div key={idx} className="flex items-center gap-2 flex-shrink-0">
            <div className="px-3 py-2 bg-gray-100 rounded-lg text-xs">
              <div className="font-medium mb-1">{process.step}</div>
              <div className="text-muted-foreground">{process.result}</div>
            </div>
            {idx < result.fusionProcess.length - 1 && (
              <ArrowRight className="w-4 h-4 text-gray-400" />
            )}
          </div>
        ))}
      </div>
    </div>
  )}
</Card>
```

### 3. 添加手动添加决策对话框

```tsx
{/* 手动添加决策对话框 */}
<Dialog open={showAddDecisionDialog} onOpenChange={setShowAddDecisionDialog}>
  <DialogContent className="max-w-3xl max-h-[90vh] overflow-y-auto">
    <DialogHeader>
      <DialogTitle>手动添加决策</DialogTitle>
      <DialogDescription>
        填写以下信息创建一个新的决策
      </DialogDescription>
    </DialogHeader>
    
    <div className="space-y-6">
      {/* 基本信息 */}
      <Card className="p-4 bg-blue-50 border-blue-200">
        <h4 className="mb-4">基本信息</h4>
        <div className="space-y-4">
          <div>
            <Label>决策名称 *</Label>
            <Input 
              placeholder="例如: 3号大棚通风决策"
              value={newDecision.name}
              onChange={(e) => setNewDecision({...newDecision, name: e.target.value})}
            />
          </div>
          
          <div className="grid grid-cols-2 gap-4">
            <div>
              <Label>决策级别 *</Label>
              <Select 
                value={newDecision.level}
                onValueChange={(v) => setNewDecision({...newDecision, level: v as DecisionLevel})}
              >
                <SelectTrigger>
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="critical">紧急</SelectItem>
                  <SelectItem value="important">重要</SelectItem>
                  <SelectItem value="normal">一般</SelectItem>
                  <SelectItem value="suggestion">建议</SelectItem>
                </SelectContent>
              </Select>
            </div>
            
            <div>
              <Label>置信度</Label>
              <Input 
                type="number"
                min="0"
                max="100"
                placeholder="0-100"
                value={newDecision.confidence * 100}
                onChange={(e) => setNewDecision({
                  ...newDecision, 
                  confidence: Number(e.target.value) / 100
                })}
              />
            </div>
          </div>
        </div>
      </Card>
      
      {/* 执行设置 */}
      <Card className="p-4 bg-green-50 border-green-200">
        <h4 className="mb-4">执行设置</h4>
        <div className="space-y-4">
          <div>
            <Label>执行模式 *</Label>
            <Select 
              value={newDecision.executionMode}
              onValueChange={(v) => setNewDecision({...newDecision, executionMode: v as ExecutionMode})}
            >
              <SelectTrigger>
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="manual">
                  <div className="flex items-center gap-2">
                    <Play className="w-4 h-4" />
                    手动执行（点击执行按钮时执行）
                  </div>
                </SelectItem>
                <SelectItem value="auto">
                  <div className="flex items-center gap-2">
                    <Zap className="w-4 h-4" />
                    自动执行（条件满足时自动执行）
                  </div>
                </SelectItem>
              </SelectContent>
            </Select>
          </div>
          
          {/* 自动执行时显示触发条件设置 */}
          {newDecision.executionMode === 'auto' && (
            <Card className="p-4 bg-yellow-50 border-yellow-200">
              <div className="flex items-center gap-2 mb-3">
                <Settings className="w-4 h-4 text-yellow-700" />
                <h5 className="text-sm font-medium">触发条件设置</h5>
              </div>
              
              <div className="space-y-3">
                <div>
                  <Label>触发类型</Label>
                  <Select value={triggerType} onValueChange={setTriggerType}>
                    <SelectTrigger>
                      <SelectValue />
                    </SelectTrigger>
                    <SelectContent>
                      <SelectItem value="threshold">阈值触发（如温度>30℃）</SelectItem>
                      <SelectItem value="time">时间触发（如每天17:00）</SelectItem>
                      <SelectItem value="event">事件触发（如突然降温）</SelectItem>
                    </SelectContent>
                  </Select>
                </div>
                
                {triggerType === 'threshold' && (
                  <div className="grid grid-cols-3 gap-2">
                    <div>
                      <Label>字段</Label>
                      <Input placeholder="如: 土壤湿度" />
                    </div>
                    <div>
                      <Label>操作符</Label>
                      <Select>
                        <SelectTrigger>
                          <SelectValue />
                        </SelectTrigger>
                        <SelectContent>
                          <SelectItem value=">">{'>'} 大于</SelectItem>
                          <SelectItem value="<">{'<'} 小于</SelectItem>
                          <SelectItem value=">=">{'≥'} 大于等于</SelectItem>
                          <SelectItem value="<=">{'≤'} 小于等于</SelectItem>
                          <SelectItem value="==">{'='} 等于</SelectItem>
                        </SelectContent>
                      </Select>
                    </div>
                    <div>
                      <Label>值</Label>
                      <Input type="number" placeholder="如: 30" />
                    </div>
                  </div>
                )}
              </div>
            </Card>
          )}
          
          <div>
            <Label>目标设备</Label>
            <Input 
              placeholder="例如: 灌溉控制器-01, 水泵-A2 (多个设备用逗号分隔)"
              value={newDecision.targetDevices?.join(', ') || ''}
              onChange={(e) => setNewDecision({
                ...newDecision, 
                targetDevices: e.target.value.split(',').map(d => d.trim()).filter(Boolean)
              })}
            />
          </div>
        </div>
      </Card>
      
      {/* 决策内容 */}
      <Card className="p-4">
        <h4 className="mb-4">决策内容</h4>
        <div className="space-y-4">
          <div>
            <Label>推荐建议 *</Label>
            <Textarea 
              placeholder="简要说明这个决策的推荐建议..."
              rows={3}
              value={newDecision.recommendation}
              onChange={(e) => setNewDecision({...newDecision, recommendation: e.target.value})}
            />
          </div>
          
          <div>
            <Label>详细说明</Label>
            <Textarea 
              placeholder="详细解释这个决策的原因、依据等..."
              rows={5}
              value={newDecision.explanation}
              onChange={(e) => setNewDecision({...newDecision, explanation: e.target.value})}
            />
          </div>
          
          <div>
            <Label>执行步骤 *（每行一个步骤）</Label>
            <Textarea 
              placeholder="例如:&#10;1. 准备灌溉设备&#10;2. 检查管道和喷头&#10;3. 开始灌溉..."
              rows={6}
              value={actionItemsText}
              onChange={(e) => setActionItemsText(e.target.value)}
            />
          </div>
        </div>
      </Card>
    </div>
    
    <DialogFooter>
      <Button variant="outline" onClick={() => setShowAddDecisionDialog(false)}>
        取消
      </Button>
      <Button onClick={handleSaveNewDecision} className="bg-green-600 hover:bg-green-700">
        <Plus className="w-4 h-4 mr-2" />
        保存决策
      </Button>
    </DialogFooter>
  </DialogContent>
</Dialog>
```

### 4. 添加编辑决策对话框

```tsx
{/* 编辑决策对话框 */}
<Dialog open={showEditDecisionDialog} onOpenChange={setShowEditDecisionDialog}>
  <DialogContent className="max-w-3xl max-h-[90vh] overflow-y-auto">
    <DialogHeader>
      <DialogTitle>编辑决策</DialogTitle>
      <DialogDescription>
        修改决策信息
      </DialogDescription>
    </DialogHeader>
    
    {editingDecision && (
      <div className="space-y-6">
        {/* 如果是自动生成的决策，显示提示 */}
        {editingDecision.source === 'auto' && (
          <Card className="p-3 bg-amber-50 border-amber-200">
            <div className="flex items-center gap-2 text-sm text-amber-800">
              <AlertCircle className="w-4 h-4" />
              <span>注意: 这是自动生成的决策，编辑后将无法还原原始融合过程</span>
            </div>
          </Card>
        )}
        
        {/* 与添加决策对话框类似的表单，但填充现有数据 */}
        ...
      </div>
    )}
    
    <DialogFooter>
      <Button variant="outline" onClick={() => setShowEditDecisionDialog(false)}>
        取消
      </Button>
      <Button onClick={handleUpdateDecision} className="bg-blue-600 hover:bg-blue-700">
        <Save className="w-4 h-4 mr-2" />
        保存修改
      </Button>
    </DialogFooter>
  </DialogContent>
</Dialog>
```

### 5. 添加处理函数

```typescript
// 筛选决策
const filteredDecisions = decisionResults.filter(d => {
  if (activeTab === 'all') return true;
  if (activeTab === 'auto') return d.source === 'auto';
  if (activeTab === 'manual') return d.source === 'manual';
  return true;
});

// 手动添加决策
const [newDecision, setNewDecision] = useState({
  name: '',
  level: 'normal' as DecisionLevel,
  confidence: 0.8,
  executionMode: 'manual' as ExecutionMode,
  targetDevices: [] as string[],
  recommendation: '',
  explanation: '',
});

const [actionItemsText, setActionItemsText] = useState('');
const [triggerType, setTriggerType] = useState('threshold');

const handleSaveNewDecision = () => {
  // 验证必填字段
  if (!newDecision.name || !newDecision.recommendation || !actionItemsText) {
    toast.error('请填写必填字段');
    return;
  }
  
  // 构建决策对象
  const decision: DecisionResult = {
    id: `decision_manual_${Date.now()}`,
    name: newDecision.name,
    source: 'manual',
    executionMode: newDecision.executionMode,
    level: newDecision.level,
    confidence: newDecision.confidence,
    recommendation: newDecision.recommendation,
    explanation: newDecision.explanation,
    actionItems: actionItemsText.split('\n').filter(Boolean),
    targetDevices: newDecision.targetDevices,
    inputData: { models: [], rules: [], context: [] },
    fusionProcess: [],
    generatedAt: new Date().toLocaleString('zh-CN'),
    createdBy: '当前用户', // 从context获取
  };
  
  // 如果是自动执行，添加触发条件
  if (newDecision.executionMode === 'auto') {
    decision.autoTriggerConditions = {
      type: triggerType as 'threshold' | 'time' | 'event',
      conditions: [
        // 从表单收集
      ],
    };
  }
  
  // 保存决策
  // decisionResults.push(decision);
  
  toast.success('决策添加成功！');
  setShowAddDecisionDialog(false);
  
  // 重置表单
  setNewDecision({
    name: '',
    level: 'normal',
    confidence: 0.8,
    executionMode: 'manual',
    targetDevices: [],
    recommendation: '',
    explanation: '',
  });
  setActionItemsText('');
};

// 编辑决策
const handleEditDecision = (decision: DecisionResult) => {
  setEditingDecision(decision);
  setShowEditDecisionDialog(true);
};

const handleUpdateDecision = () => {
  // 更新决策
  toast.success('决策更新成功！');
  setShowEditDecisionDialog(false);
};
```

### 6. 更新执行确认对话框

在执行确认对话框中显示执行模式：

```tsx
{executingResult && (
  <div className="space-y-4">
    {/* 决策信息 */}
    <Card className="p-4 bg-blue-50 border-blue-200">
      <div className="flex items-start gap-3">
        <AlertCircle className="w-5 h-5 text-blue-600 flex-shrink-0 mt-0.5" />
        <div>
          <div className="font-medium mb-1">{executingResult.name}</div>
          <div className="text-sm text-muted-foreground mb-2">
            {executingResult.recommendation}
          </div>
          <div className="flex items-center gap-4 text-xs">
            <div className="flex items-center gap-1">
              <Gauge className="w-3 h-3 text-green-600" />
              <span>置信度 {(executingResult.confidence * 100).toFixed(0)}%</span>
            </div>
            {getDecisionLevelBadge(executingResult.level)}
            
            {/* 来源标识 */}
            {executingResult.source === 'auto' ? (
              <Badge variant="outline" className="bg-purple-50 text-purple-700">
                <Brain className="w-3 h-3 mr-1" />
                自动生成
              </Badge>
            ) : (
              <Badge variant="outline" className="bg-blue-50 text-blue-700">
                <Edit className="w-3 h-3 mr-1" />
                手动添加 by {executingResult.createdBy}
              </Badge>
            )}
          </div>
        </div>
      </div>
    </Card>
    
    {/* 目标设备 */}
    {executingResult.targetDevices && executingResult.targetDevices.length > 0 && (
      <div>
        <h5 className="text-sm font-medium mb-2">将控制以下设备：</h5>
        <div className="grid grid-cols-3 gap-2">
          {executingResult.targetDevices.map((device, idx) => (
            <Card key={idx} className="p-3 bg-gray-50">
              <div className="flex items-center gap-2">
                <Activity className="w-4 h-4 text-blue-600" />
                <span className="text-sm">{device}</span>
              </div>
            </Card>
          ))}
        </div>
      </div>
    )}
    
    {/* 执行步骤预览 */}
    ...
  </div>
)}
```

## 📊 实施优先级

### P0（必须）
- [x] 数据结构更新
- [ ] 添加"手动添加决策"按钮
- [ ] 添加手动添加决策对话框
- [ ] 添加来源和执行模式标识
- [ ] 添加决策分类Tab

### P1（重要）
- [ ] 添加编辑决策功能
- [ ] 添加自动执行触发条件显示
- [ ] 添加目标设备显示
- [ ] 更新执行确认对话框

### P2（可选）
- [ ] 添加删除决策功能
- [ ] 添加复制决策功能
- [ ] 添加导入导出功能

## ✅ 验收标准

1. [ ] 可以手动添加决策
2. [ ] 可以设置执行模式（手动/自动）
3. [ ] 自动执行可以设置触发条件
4. [ ] 可以编辑决策
5. [ ] 可以按来源分类查看
6. [ ] 决策卡片正确显示所有信息
7. [ ] 执行时正确识别执行模式

---

**创建时间**: 2024-10-23
**状态**: 待实施
