Files
deerflow-code/web-code/components/taskManagement/TaskConsult.tsx
T
2026-05-27 19:43:15 +08:00

627 lines
30 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import React, { useState } from 'react';
import {
ArrowLeft,
Bot,
Users,
Play,
Pause,
Download,
CheckCircle,
ChevronRight,
MessageSquare,
Send,
Star,
AlertCircle,
FileText,
Settings,
Lightbulb,
Zap,
Check,
X,
Minus,
} from 'lucide-react';
import { useTheme } from '@/contexts/ThemeContext';
import { PageType } from '@/components/Sidebar';
interface TaskConsultProps {
onNavigate: (page: PageType) => void;
}
// 模拟参与智能体
const participants = [
{
id: 'goal',
name: 'GoalAgent',
role: '目标分析专家',
color: 'blue',
status: 'idle' as const,
lastOpinion: '建议聚焦提升品牌认知度这一核心目标',
},
{
id: 'audience',
name: 'AudienceAgent',
role: '受众分析专家',
color: 'cyan',
status: 'speaking' as const,
lastOpinion: '核心受众应为18-25岁基层青年群体',
},
{
id: 'narrative',
name: 'NarrativeAgent',
role: '叙事策略专家',
color: 'purple',
status: 'idle' as const,
lastOpinion: '应采用真实、有态度的青年故事叙事',
},
{
id: 'risk',
name: 'RiskAgent',
role: '风险评估专家',
color: 'red',
status: 'idle' as const,
lastOpinion: '需注意UGC质量不稳定和话题热度维持的风险',
},
];
// 模拟讨论记录
const discussionRecords = [
{
id: 1,
agentId: 'goal',
agentName: 'GoalAgent',
agentRole: '目标分析专家',
color: 'blue',
content: `从目标分析角度看,这次五四青年节宣传活动应聚焦以下核心目标:
**主目标**:提升品牌在Z世代用户中的认知度
**量化指标建议**:
- 曝光量:500万+
- 互动率:5%+
- UGC数量:1000+
**优先级判断**:
建议优先聚焦品牌认知度提升,短期内不追求直接转化。这样可以更好地与目标受众建立情感连接。`,
time: '14:30',
tags: ['核心目标', '品牌认知'],
markedAs: null as string | null,
},
{
id: 2,
agentId: 'audience',
agentName: 'AudienceAgent',
agentRole: '受众分析专家',
color: 'cyan',
content: `基于受众分析,我建议:
**核心受众画像**:
- 年龄:18-25岁
- 身份:学生、基层青年工作者
- 地域:一二线城市为主
**关键洞察**:
这部分群体是社交媒体重度用户,注重"真实感"和"态度感",反感过度营销。需要用平等对话的方式,而非说教式传播。
**内容偏好**:
真实故事 > 精致包装
态度表达 > 信息堆砌
参与互动 > 被动观看`,
time: '14:32',
tags: ['受众画像', '内容偏好'],
markedAs: 'valuable' as string | null,
},
{
id: 3,
agentId: 'narrative',
agentName: 'NarrativeAgent',
agentRole: '叙事策略专家',
color: 'purple',
content: `从叙事策略角度,我建议采用以下框架:
**叙事主题**:真实、有态度的青年故事
**叙事结构**:
1. 讲述真实的人物故事
2. 引发情感共鸣
3. 传递品牌价值观
4. 激发用户参与
**关键要素**:
- 真实感 > 精致感
- 态度感 > 说教感
- 参与感 > 观看感
**内容类型建议**:
- 人物专访型:真实青年故事
- 事件记录型:青年节活动现场
- 观点表达型:青年态度宣言`,
time: '14:35',
tags: ['叙事框架', '内容类型'],
markedAs: null as string | null,
},
{
id: 4,
agentId: 'risk',
agentName: 'RiskAgent',
agentRole: '风险评估专家',
color: 'red',
content: `我需要提醒以下风险:
**高风险项**:
1. 内容质量不稳定
- 风险:UGC质量参差不齐
- 对策:建立内容审核机制
**中风险项**:
2. 预算控制难度大
- 风险:投放效果不可控
- 对策:分阶段预算分配
3. 青年群体注意力分散
- 风险:话题热度难维持
- 对策:多波次内容规划
**建议**:重点关注内容质量风险,建立审核机制。`,
time: '14:38',
tags: ['风险识别', '应对建议'],
markedAs: 'pending' as string | null,
},
];
const TaskConsult: React.FC<TaskConsultProps> = ({ onNavigate }) => {
const { theme } = useTheme();
const isDark = theme === 'dark';
const [isPaused, setIsPaused] = useState(false);
const [currentRound, setCurrentRound] = useState(2);
const [currentTopic, setCurrentTopic] = useState('宣传策略方向选择');
const [humanInput, setHumanInput] = useState('');
const [consensusPoints] = useState([
'核心受众应聚焦18-25岁基层青年',
'内容应以真实、有态度为核心',
]);
const [disputedPoints] = useState([
'叙事角度:事件叙事 vs 人物叙事',
'传播渠道:短视频平台 vs 社交媒体',
]);
const [humanNotes, setHumanNotes] = useState('');
const getColorClasses = (color: string) => {
const colors: Record<string, { bg: string; border: string; text: string }> = {
blue: { bg: isDark ? 'bg-blue-500/20' : 'bg-blue-50', border: isDark ? 'border-blue-500/50' : 'border-blue-200', text: isDark ? 'text-blue-400' : 'text-blue-600' },
cyan: { bg: isDark ? 'bg-cyan-500/20' : 'bg-cyan-50', border: isDark ? 'border-cyan-500/50' : 'border-cyan-200', text: isDark ? 'text-cyan-400' : 'text-cyan-600' },
green: { bg: isDark ? 'bg-green-500/20' : 'bg-green-50', border: isDark ? 'border-green-500/50' : 'border-green-200', text: isDark ? 'text-green-400' : 'text-green-600' },
yellow: { bg: isDark ? 'bg-yellow-500/20' : 'bg-yellow-50', border: isDark ? 'border-yellow-500/50' : 'border-yellow-200', text: isDark ? 'text-yellow-400' : 'text-yellow-600' },
purple: { bg: isDark ? 'bg-purple-500/20' : 'bg-purple-50', border: isDark ? 'border-purple-500/50' : 'border-purple-200', text: isDark ? 'text-purple-400' : 'text-purple-600' },
red: { bg: isDark ? 'bg-red-500/20' : 'bg-red-50', border: isDark ? 'border-red-500/50' : 'border-red-200', text: isDark ? 'text-red-400' : 'text-red-600' },
};
return colors[color] || colors.blue;
};
const getStatusConfig = (status: string) => {
switch (status) {
case 'speaking':
return { label: '发言中', color: isDark ? 'bg-green-500/20 text-green-400' : 'bg-green-100 text-green-700', dot: isDark ? 'bg-green-400' : 'bg-green-500' };
case 'completed':
return { label: '已完成', color: isDark ? 'bg-slate-500/20 text-slate-400' : 'bg-gray-100 text-gray-600', dot: isDark ? 'bg-slate-400' : 'bg-gray-400' };
default:
return { label: '待发言', color: isDark ? 'bg-slate-500/20 text-slate-400' : 'bg-gray-100 text-gray-600', dot: isDark ? 'bg-slate-400' : 'bg-gray-400' };
}
};
const handleNextRound = () => {
setCurrentRound(currentRound + 1);
};
const handleFinishConsult = () => {
onNavigate('task-consult-result');
};
// 主题颜色类
const cardBg = isDark ? 'bg-slate-800/30' : 'bg-white';
const cardBorder = isDark ? 'border-blue-800/30' : 'border-red-200';
const textPrimary = isDark ? 'text-white' : 'text-gray-900';
const textSecondary = isDark ? 'text-slate-400' : 'text-gray-600';
const textMuted = isDark ? 'text-slate-500' : 'text-gray-500';
const btnSecondary = isDark ? 'bg-slate-700/50 hover:bg-slate-600/50 border-blue-800/30 text-slate-300' : 'bg-gray-100 hover:bg-gray-200 border-gray-300 text-gray-700';
const btnPrimary = isDark ? 'bg-blue-600 hover:bg-blue-500' : 'bg-red-600 hover:bg-red-500';
const inputBg = isDark ? 'bg-slate-900/50' : 'bg-gray-50';
const inputBorder = isDark ? 'border-blue-800/30' : 'border-gray-300';
return (
<div className="h-[calc(100vh-140px)] flex flex-col space-y-4">
{/* 顶部信息栏 */}
<div className={`${cardBg} backdrop-blur-xl border ${cardBorder} rounded-xl p-4 flex-shrink-0`}>
<div className="flex items-center justify-between">
<div className="flex items-center gap-4">
<button
onClick={() => onNavigate('task-list')}
className={`flex items-center gap-2 px-3 py-2 ${btnSecondary} rounded-lg text-sm transition-colors`}
>
<ArrowLeft className="w-4 h-4" />
返回
</button>
<div className={`h-8 w-px ${isDark ? 'bg-blue-800/30' : 'bg-red-200'}`} />
<div>
<h1 className={`${textPrimary} font-bold text-lg`}>五四青年节宣传策略会商</h1>
<p className={`${textSecondary} text-sm`}>多智能体会商任务 · 第 {currentRound} 轮</p>
</div>
</div>
<div className="flex items-center gap-4">
<div className="flex items-center gap-4 text-sm">
<span className={textSecondary}>
模式:<span className={isDark ? 'text-purple-400' : 'text-purple-600'}>受控交叉讨论</span>
</span>
<span className={textSecondary}>
参与:<span className={isDark ? 'text-cyan-400' : 'text-cyan-600'}>{participants.length} 个智能体</span>
</span>
<span className={textSecondary}>
创建:<span className={textPrimary}>2026-03-19 14:30</span>
</span>
</div>
<div className={`h-8 w-px ${isDark ? 'bg-blue-800/30' : 'bg-red-200'}`} />
<div className="flex items-center gap-2">
<button
onClick={() => setIsPaused(!isPaused)}
className={`flex items-center gap-2 px-3 py-1.5 rounded-lg text-sm transition-colors ${
isPaused
? (isDark ? 'bg-green-500/20 hover:bg-green-500/30 border-green-500/50 text-green-400' : 'bg-green-100 hover:bg-green-200 border-green-300 text-green-700')
: (isDark ? 'bg-yellow-500/20 hover:bg-yellow-500/30 border-yellow-500/50 text-yellow-400' : 'bg-yellow-100 hover:bg-yellow-200 border-yellow-300 text-yellow-700')
}`}
>
{isPaused ? <Play className="w-4 h-4" /> : <Pause className="w-4 h-4" />}
{isPaused ? '继续会商' : '暂停会商'}
</button>
<button className={`flex items-center gap-2 px-3 py-1.5 ${btnSecondary} rounded-lg text-sm transition-colors`}>
<Download className="w-4 h-4" />
导出纪要
</button>
<button
onClick={handleFinishConsult}
className="flex items-center gap-2 px-3 py-1.5 bg-orange-600 hover:bg-orange-500 text-white rounded-lg text-sm transition-colors"
>
<CheckCircle className="w-4 h-4" />
结束并整合
</button>
</div>
</div>
</div>
</div>
{/* 三栏主体区域 */}
<div className="flex-1 grid grid-cols-12 gap-4 min-h-0">
{/* 左栏:参与智能体与议题导航 */}
<div className="col-span-3 flex flex-col gap-4 min-h-0">
{/* 参与智能体 */}
<div className={`${cardBg} backdrop-blur-xl border ${cardBorder} rounded-xl p-4 flex-1 overflow-hidden flex flex-col`}>
<h3 className={`${textPrimary} font-semibold text-sm mb-3 flex items-center gap-2`}>
<Users className={`w-4 h-4 ${isDark ? 'text-purple-400' : 'text-purple-600'}`} />
参与智能体
</h3>
<div className="space-y-2 flex-1 overflow-y-auto">
{participants.map((agent) => {
const colors = getColorClasses(agent.color);
const statusConfig = getStatusConfig(agent.status);
return (
<div
key={agent.id}
className={`p-3 rounded-lg border transition-all ${
agent.status === 'speaking'
? `${colors.bg} ${colors.border}`
: isDark ? 'bg-slate-900/50 border-blue-800/30' : 'bg-gray-50 border-gray-200'
}`}
>
<div className="flex items-center justify-between mb-2">
<div className="flex items-center gap-2">
<div className={`w-8 h-8 rounded-lg ${colors.bg} flex items-center justify-center`}>
<Bot className={`w-4 h-4 ${colors.text}`} />
</div>
<div>
<p className={`text-sm font-medium ${agent.status === 'speaking' ? colors.text : textPrimary}`}>
{agent.name}
</p>
<p className={`${textMuted} text-xs`}>{agent.role}</p>
</div>
</div>
<span className={`px-1.5 py-0.5 rounded text-xs ${statusConfig.color}`}>
{statusConfig.label}
</span>
</div>
{agent.lastOpinion && (
<p className={`${textSecondary} text-xs line-clamp-2 pl-10`}>{agent.lastOpinion}</p>
)}
<button
className={`mt-2 w-full px-2 py-1.5 rounded text-xs transition-colors ${
agent.status === 'speaking'
? (isDark ? 'bg-slate-700/50 text-slate-400 cursor-not-allowed' : 'bg-gray-200 text-gray-500 cursor-not-allowed')
: (isDark ? 'bg-purple-500/20 hover:bg-purple-500/30 text-purple-400' : 'bg-purple-100 hover:bg-purple-200 text-purple-700')
}`}
disabled={agent.status === 'speaking'}
>
点名发言
</button>
</div>
);
})}
</div>
</div>
{/* 会商议题导航 */}
<div className={`${cardBg} backdrop-blur-xl border ${cardBorder} rounded-xl p-4`}>
<h3 className={`${textPrimary} font-semibold text-sm mb-3 flex items-center gap-2`}>
<MessageSquare className={`w-4 h-4 ${isDark ? 'text-blue-400' : 'text-blue-600'}`} />
会商议题
</h3>
<div className="space-y-2">
<div className={`p-3 rounded-lg border ${isDark ? 'bg-green-500/20 border-green-500/50' : 'bg-green-50 border-green-300'}`}>
<p className={`text-sm font-medium ${isDark ? 'text-green-400' : 'text-green-700'}`}>当前议题</p>
<p className={`${textPrimary} text-sm mt-1`}>{currentTopic}</p>
</div>
<div className={`p-3 rounded-lg border ${isDark ? 'bg-slate-900/50 border-blue-800/30' : 'bg-gray-50 border-gray-200'}`}>
<p className={`${textMuted} text-xs mb-1`}>待讨论</p>
<p className={isDark ? 'text-slate-300 text-sm' : 'text-gray-700 text-sm'}>渠道策略选择</p>
<p className={isDark ? 'text-slate-300 text-sm' : 'text-gray-700 text-sm'}>预算分配方案</p>
</div>
<div className={`p-3 rounded-lg border ${isDark ? 'bg-slate-900/50 border-blue-800/30' : 'bg-gray-50 border-gray-200'}`}>
<p className={`${textMuted} text-xs mb-1`}>已讨论</p>
<p className={`${textMuted} text-sm line-through`}>受众定位</p>
<p className={`${textMuted} text-sm line-through`}>目标设定</p>
</div>
</div>
<div className="mt-3 flex gap-2">
<button className={`flex-1 px-2 py-1.5 ${btnSecondary} rounded-lg text-xs transition-colors`}>
切换议题
</button>
<button className={`flex-1 px-2 py-1.5 ${btnSecondary} rounded-lg text-xs transition-colors`}>
结束议题
</button>
</div>
</div>
</div>
{/* 中栏:会商讨论区 */}
<div className="col-span-6 flex flex-col gap-4 min-h-0">
{/* 当前议题卡 */}
<div className={`${cardBg} backdrop-blur-xl border ${cardBorder} rounded-xl p-4 flex-shrink-0`}>
<div className="flex items-center justify-between">
<div>
<p className={`${textSecondary} text-xs`}>当前议题</p>
<p className={`${textPrimary} font-medium mt-0.5`}>{currentTopic}</p>
</div>
<div className="flex items-center gap-3">
<span className={`px-2 py-1 rounded text-xs ${isDark ? 'bg-purple-500/20 text-purple-400' : 'bg-purple-100 text-purple-700'}`}>
受控交叉讨论模式
</span>
<span className={`px-2 py-1 rounded text-xs ${isDark ? 'bg-blue-500/20 text-blue-400' : 'bg-blue-100 text-blue-700'}`}>
第 {currentRound} 轮
</span>
</div>
</div>
</div>
{/* 讨论流 */}
<div className={`${cardBg} backdrop-blur-xl border ${cardBorder} rounded-xl overflow-hidden flex flex-col`}>
<div className={`p-4 border-b ${isDark ? 'border-blue-800/30' : 'border-gray-200'} flex items-center justify-between`}>
<h3 className={`${textPrimary} font-semibold text-sm`}>讨论记录</h3>
<button
onClick={handleNextRound}
className={`flex items-center gap-2 px-3 py-1.5 ${btnPrimary} bg-opacity-20 hover:bg-opacity-30 ${isDark ? 'border border-blue-500/30 text-blue-400' : 'border border-red-400 text-red-600'} rounded-lg text-xs transition-colors`}
>
<ChevronRight className="w-4 h-4" />
下一轮
</button>
</div>
<div className="flex-1 overflow-y-auto p-4 space-y-4">
{discussionRecords.map((record) => {
const colors = getColorClasses(record.color);
return (
<div
key={record.id}
className={`p-4 rounded-xl border ${
record.markedAs === 'valuable'
? (isDark ? 'bg-green-500/10 border-green-500/30' : 'bg-green-50 border-green-300')
: record.markedAs === 'pending'
? (isDark ? 'bg-yellow-500/10 border-yellow-500/30' : 'bg-yellow-50 border-yellow-300')
: (isDark ? 'bg-slate-900/50 border-blue-800/30' : 'bg-gray-50 border-gray-200')
}`}
>
<div className="flex items-start justify-between mb-3">
<div className="flex items-center gap-3">
<div className={`w-10 h-10 rounded-lg ${colors.bg} flex items-center justify-center`}>
<Bot className={`w-5 h-5 ${colors.text}`} />
</div>
<div>
<div className="flex items-center gap-2">
<p className={`text-sm font-medium ${colors.text}`}>{record.agentName}</p>
{record.markedAs === 'valuable' && (
<span className={`px-1.5 py-0.5 rounded text-xs flex items-center gap-0.5 ${isDark ? 'bg-green-500/20 text-green-400' : 'bg-green-100 text-green-700'}`}>
<Star className="w-3 h-3" /> 有价值
</span>
)}
{record.markedAs === 'pending' && (
<span className={`px-1.5 py-0.5 rounded text-xs flex items-center gap-0.5 ${isDark ? 'bg-yellow-500/20 text-yellow-400' : 'bg-yellow-100 text-yellow-700'}`}>
<AlertCircle className="w-3 h-3" /> 待验证
</span>
)}
</div>
<p className={`${textMuted} text-xs`}>{record.agentRole} · {record.time}</p>
</div>
</div>
<div className="flex items-center gap-1">
<button
className={`p-1.5 rounded transition-colors ${isDark ? 'hover:bg-green-500/20' : 'hover:bg-green-100'}`}
title="标记为有价值"
>
<Star className={`w-4 h-4 ${isDark ? 'text-slate-400 hover:text-green-400' : 'text-gray-500 hover:text-green-600'}`} />
</button>
<button
className={`p-1.5 rounded transition-colors ${isDark ? 'hover:bg-yellow-500/20' : 'hover:bg-yellow-100'}`}
title="标记为待验证"
>
<AlertCircle className={`w-4 h-4 ${isDark ? 'text-slate-400 hover:text-yellow-400' : 'text-gray-500 hover:text-yellow-600'}`} />
</button>
<button
className={`p-1.5 rounded transition-colors ${isDark ? 'hover:bg-red-500/20' : 'hover:bg-red-100'}`}
title="暂不采纳"
>
<X className={`w-4 h-4 ${isDark ? 'text-slate-400 hover:text-red-400' : 'text-gray-500 hover:text-red-600'}`} />
</button>
</div>
</div>
<div className="pl-13">
<div className={`${isDark ? 'text-slate-300' : 'text-gray-700'} text-sm whitespace-pre-wrap leading-relaxed`}>
{record.content}
</div>
<div className="flex items-center gap-2 mt-3">
{record.tags.map((tag) => (
<span key={tag} className={`px-2 py-0.5 rounded text-xs ${isDark ? 'bg-blue-500/20 text-blue-400' : 'bg-blue-100 text-blue-700'}`}>
{tag}
</span>
))}
</div>
<div className="flex items-center gap-2 mt-3">
<button className={`flex items-center gap-1 px-2 py-1 ${btnSecondary} rounded text-xs transition-colors`}>
<FileText className="w-3 h-3" />
引用到整合区
</button>
</div>
</div>
</div>
);
})}
</div>
</div>
{/* 人工发言区 */}
<div className={`${cardBg} backdrop-blur-xl border ${cardBorder} rounded-xl p-4 flex-shrink-0`}>
<div className="flex items-start gap-3">
<div className={`w-10 h-10 rounded-lg flex items-center justify-center flex-shrink-0 ${isDark ? 'bg-blue-500/20' : 'bg-blue-100'}`}>
<Users className={`w-5 h-5 ${isDark ? 'text-blue-400' : 'text-blue-600'}`} />
</div>
<div className="flex-1">
<textarea
value={humanInput}
onChange={(e) => setHumanInput(e.target.value)}
placeholder="输入您的评论、问题或指令... (可点名某个智能体:@GoalAgent)"
rows={2}
className={`w-full px-4 py-2.5 ${inputBg} border ${inputBorder} rounded-lg ${textPrimary} text-sm ${isDark ? 'placeholder-slate-500' : 'placeholder-gray-400'} focus:outline-none ${isDark ? 'focus:border-blue-500/50' : 'focus:border-red-400'} transition-colors resize-none`}
/>
<div className="flex items-center justify-between mt-2">
<div className="flex items-center gap-2">
<button className={`px-2 py-1 ${btnSecondary} rounded text-xs transition-colors`}>
点名提问
</button>
<button className={`px-2 py-1 ${btnSecondary} rounded text-xs transition-colors`}>
发起对比问题
</button>
<button className={`px-2 py-1 ${btnSecondary} rounded text-xs transition-colors`}>
要求补充说明
</button>
</div>
<button
disabled={!humanInput.trim()}
className={`flex items-center gap-2 px-4 py-2 ${btnPrimary} disabled:${isDark ? 'bg-slate-700 text-slate-500' : 'bg-gray-300 text-gray-500'} text-white rounded-lg text-sm transition-colors`}
>
<Send className="w-4 h-4" />
发送
</button>
</div>
</div>
</div>
</div>
</div>
{/* 右栏:观点整合区 */}
<div className="col-span-3 flex flex-col gap-4 min-h-0">
{/* 各智能体核心观点 */}
<div className={`${cardBg} backdrop-blur-xl border ${cardBorder} rounded-xl p-4 flex-1 overflow-hidden flex flex-col`}>
<h3 className={`${textPrimary} font-semibold text-sm mb-3 flex items-center gap-2`}>
<Bot className={`w-4 h-4 ${isDark ? 'text-cyan-400' : 'text-cyan-600'}`} />
各方观点
</h3>
<div className="space-y-3 flex-1 overflow-y-auto">
{participants.map((agent) => {
const colors = getColorClasses(agent.color);
return (
<div key={agent.id} className={`p-3 rounded-lg ${isDark ? 'bg-slate-900/50 border-blue-800/30' : 'bg-gray-50 border-gray-200'}`}>
<div className="flex items-center gap-2 mb-2">
<Bot className={`w-4 h-4 ${colors.text}`} />
<span className={`text-sm font-medium ${colors.text}`}>{agent.name}</span>
</div>
<p className={`${textSecondary} text-xs line-clamp-3`}>{agent.lastOpinion}</p>
</div>
);
})}
</div>
</div>
{/* 共识观点 */}
<div className={`${cardBg} backdrop-blur-xl border ${isDark ? 'border-green-800/30' : 'border-green-300'} rounded-xl p-4`}>
<h3 className={`${textPrimary} font-semibold text-sm mb-3 flex items-center gap-2`}>
<Check className={`w-4 h-4 ${isDark ? 'text-green-400' : 'text-green-600'}`} />
共识观点
<span className={`px-1.5 py-0.5 rounded text-xs ml-auto ${isDark ? 'bg-green-500/20 text-green-400' : 'bg-green-100 text-green-700'}`}>
{consensusPoints.length} 条
</span>
</h3>
<div className="space-y-2">
{consensusPoints.map((point, index) => (
<div key={index} className={`p-2 rounded-lg ${isDark ? 'bg-green-500/10 border border-green-500/30' : 'bg-green-50 border border-green-200'}`}>
<p className={isDark ? 'text-green-300 text-sm' : 'text-green-800 text-sm'}>{point}</p>
</div>
))}
</div>
</div>
{/* 分歧观点 */}
<div className={`${cardBg} backdrop-blur-xl border ${isDark ? 'border-yellow-800/30' : 'border-yellow-300'} rounded-xl p-4`}>
<h3 className={`${textPrimary} font-semibold text-sm mb-3 flex items-center gap-2`}>
<Minus className={`w-4 h-4 ${isDark ? 'text-yellow-400' : 'text-yellow-600'}`} />
分歧观点
<span className={`px-1.5 py-0.5 rounded text-xs ml-auto ${isDark ? 'bg-yellow-500/20 text-yellow-400' : 'bg-yellow-100 text-yellow-700'}`}>
{disputedPoints.length} 条
</span>
</h3>
<div className="space-y-2">
{disputedPoints.map((point, index) => (
<div key={index} className={`p-2 rounded-lg ${isDark ? 'bg-yellow-500/10 border border-yellow-500/30' : 'bg-yellow-50 border border-yellow-200'}`}>
<p className={isDark ? 'text-yellow-300 text-sm' : 'text-yellow-800 text-sm'}>{point}</p>
</div>
))}
</div>
</div>
{/* 人工整合区 */}
<div className={`${cardBg} backdrop-blur-xl border ${isDark ? 'border-purple-800/30' : 'border-purple-300'} rounded-xl p-4 flex-1 overflow-hidden flex flex-col`}>
<h3 className={`${textPrimary} font-semibold text-sm mb-3 flex items-center gap-2`}>
<Zap className={`w-4 h-4 ${isDark ? 'text-purple-400' : 'text-purple-600'}`} />
人工整合
</h3>
<textarea
value={humanNotes}
onChange={(e) => setHumanNotes(e.target.value)}
placeholder="记录您的判断、暂定方向、待确认事项..."
className={`flex-1 min-h-[120px] px-3 py-2 ${inputBg} border ${inputBorder} rounded-lg ${textPrimary} text-sm ${isDark ? 'placeholder-slate-500' : 'placeholder-gray-400'} focus:outline-none ${isDark ? 'focus:border-blue-500/50' : 'focus:border-red-400'} transition-colors resize-none`}
/>
<div className="flex flex-col gap-2 mt-3">
<button className={`w-full flex items-center justify-center gap-2 px-3 py-2 ${isDark ? 'bg-purple-600 hover:bg-purple-500' : 'bg-purple-600 hover:bg-purple-500'} text-white rounded-lg text-xs font-medium transition-colors`}>
<Lightbulb className="w-4 h-4" />
生成会商结论
</button>
<button className={`w-full flex items-center justify-center gap-2 px-3 py-2 ${btnSecondary} rounded-lg text-xs transition-colors`}>
<FileText className="w-4 h-4" />
转为任务摘要
</button>
<button className={`w-full flex items-center justify-center gap-2 px-3 py-2 ${btnSecondary} rounded-lg text-xs transition-colors`}>
<Settings className="w-4 h-4" />
转为场景任务输入
</button>
</div>
</div>
</div>
</div>
</div>
);
};
export default TaskConsult;