代码修改

This commit is contained in:
fengxiangdebaozi committed 2026-05-27 19:43:15 +08:00
1 parent 8f5af46ec2
commit 8f75e12871
168 files changed
+76575

No files matched your search

@@ -0,0 +1,935 @@
import React, { useState } from 'react';
import {
Target,
Clock,
User,
ChevronRight,
Play,
RotateCcw,
Download,
MessageSquare,
AlertTriangle,
CheckCircle,
Bot,
FileText,
Lightbulb,
ArrowRight,
RefreshCw,
Pause,
Eye,
Zap,
Shield,
AlertCircle,
UserCheck,
CheckCircle2,
XCircle,
Send,
Plus,
AtSign,
FileInput,
} from 'lucide-react';
import { useTheme } from '@/contexts/ThemeContext';
import { PageType } from '@/components/Sidebar';
interface TaskWorkspaceProps {
onNavigate: (page: PageType) => void;
}
const TaskWorkspace: React.FC<TaskWorkspaceProps> = ({ onNavigate }) => {
const { theme } = useTheme();
const isDark = theme === 'dark';
const [currentPhase, setCurrentPhase] = useState(3);
const [showHumanIntervention, setShowHumanIntervention] = useState(false);
const [inputType, setInputType] = useState('question');
const [sendTarget, setSendTarget] = useState('current');
const [inputMessage, setInputMessage] = useState('');
// 逻辑链一致性检查数据
const logicChainChecks = [
{ id: 'goal-behavior', label: '目标-行为', status: 'passed', detail: '行为与目标高度一致' },
{ id: 'behavior-driver', label: '行为-驱动', status: 'passed', detail: '驱动有效支撑行为' },
{ id: 'driver-narrative', label: '驱动-叙事', status: 'passed', detail: '叙事与驱动匹配' },
{ id: 'narrative-audience', label: '叙事-受众', status: 'warning', detail: '叙事需进一步收窄以匹配核心受众' },
];
// 待确认问题列表
const pendingQuestions = [
{ id: 1, type: 'field', title: '受众范围收窄', description: '是否聚焦基层青年而非全体青年?', priority: 'high' },
{ id: 2, type: 'conflict', title: '叙事方向待定', description: '真实性与话题性如何平衡?', priority: 'medium' },
];
const phases = [
{ id: 1, name: '目标分析', agent: 'GoalAgent', status: 'completed' },
{ id: 2, name: '受众分析', agent: 'AudienceAgent', status: 'completed' },
{ id: 3, name: '行为分析', agent: 'BehaviorAgent', status: 'active' },
{ id: 4, name: '驱动分析', agent: 'DriverAgent', status: 'pending' },
{ id: 5, name: '叙事分析', agent: 'NarrativeAgent', status: 'pending' },
{ id: 6, name: '逻辑链收敛', agent: 'LogicChainAgent', status: 'pending' },
{ id: 7, name: '风险评估', agent: 'RiskAgent', status: 'pending' },
{ id: 8, name: '方案生成', agent: 'DraftAgent', status: 'pending' },
];
const discussionCards = [
{
id: 1,
agent: 'GoalAgent',
phase: '目标分析',
time: '10:32',
type: 'judgment',
coreJudgment: '核心目标是提升品牌在年轻群体中的认知度和好感度',
outputFields: {
primary_goal: '提升品牌在Z世代用户中的认知度',
secondary_goal: '建立品牌年轻化形象',
},
releaseStatus: 'passed',
riskWarnings: [],
},
{
id: 2,
agent: 'AudienceAgent',
phase: '受众分析',
time: '11:15',
type: 'judgment',
coreJudgment: '核心受众应聚焦18-25岁基层青年群体,次级受众为25-30岁职场新人',
outputFields: {
core_audience: '18-25岁基层青年',
secondary_audience: '25-30岁职场新人',
audience_insights: ['社交媒体重度用户', '注重性价比', '偏好真实、有态度的品牌'],
},
releaseStatus: 'passed',
riskWarnings: ['受众范围可能过宽,建议进一步细化'],
},
{
id: 3,
agent: 'BehaviorAgent',
phase: '行为分析',
time: '14:20',
type: 'response',
coreJudgment: '目标行为是促使受众主动参与互动并生成UGC内容',
outputFields: {
target_behavior: '主动参与话题讨论、生成UGC内容',
key_conversion: '浏览 → 点赞 → 评论 → 转发 → 创作',
},
releaseStatus: 'pending',
riskWarnings: [],
},
];
const confirmedFields = {
goal: '提升品牌在Z世代用户中的认知度',
audience: '18-25岁基层青年',
behavior: '主动参与互动并生成UGC内容',
driver: '待分析',
narrative: '待分析',
};
const currentPhaseName = phases.find(p => p.status === 'active')?.name || '未知';
return (
<div className="h-[calc(100vh-140px)] flex flex-col">
{/* 顶部:运行状态栏(精简版 - 无流程图) */}
<div className={`rounded-xl p-4 flex-shrink-0 border ${
isDark ? 'bg-slate-800/30 backdrop-blur-xl border-blue-800/30' : 'bg-white border-red-100 shadow-sm'
}`}>
<div className="flex items-center justify-between">
{/* 左侧:当前阶段和运行状态 */}
<div className="flex items-center gap-6">
<div className="flex items-center gap-3">
<div className={`w-10 h-10 rounded-lg flex items-center justify-center ${
isDark ? 'bg-blue-500/20' : 'bg-red-100'
}`}>
<Target className={`w-5 h-5 ${isDark ? 'text-blue-400' : 'text-red-500'}`} />
</div>
<div>
<p className={`text-xs ${isDark ? 'text-slate-400' : 'text-gray-500'}`}>当前阶段</p>
<p className={`font-semibold ${isDark ? 'text-white' : 'text-gray-900'}`}>{currentPhaseName}</p>
</div>
</div>
<div className={`h-8 w-px ${isDark ? 'bg-blue-800/30' : 'bg-red-200'}`} />
<span className={`px-3 py-1.5 rounded-full text-sm font-medium flex items-center gap-1.5 ${
isDark
? 'bg-blue-500/20 text-blue-400'
: 'bg-red-100 text-red-600'
}`}>
<span className={`w-2 h-2 rounded-full animate-pulse ${
isDark ? 'bg-blue-400' : 'bg-red-500'
}`} />
运行中
</span>
</div>
{/* 右侧:全局操作按钮 */}
<div className="flex items-center gap-2">
<button className={`flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-sm transition-colors border ${
isDark
? 'bg-yellow-500/20 hover:bg-yellow-500/30 border-yellow-500/30 text-yellow-400'
: 'bg-yellow-100 hover:bg-yellow-200 border-yellow-200 text-yellow-600'
}`}>
<Pause className="w-4 h-4" />
暂停
</button>
<button className={`flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-sm transition-colors ${
isDark
? 'bg-green-600 hover:bg-green-500 text-white'
: 'bg-green-600 hover:bg-green-500 text-white shadow-md'
}`}>
<Play className="w-4 h-4" />
开始
</button>
<button
onClick={() => onNavigate('strategy-result')}
className={`flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-sm transition-colors border ${
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-200 text-gray-700'
}`}
>
<Eye className="w-4 h-4" />
查看结果
</button>
<button className={`flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-sm transition-colors border ${
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-200 text-gray-700'
}`}>
<Download className="w-4 h-4" />
导出
</button>
<button className={`p-2 rounded-lg transition-colors border ${
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-200 text-gray-700'
}`}>
<ChevronRight className="w-4 h-4" />
</button>
</div>
</div>
</div>
{/* 三栏式主工作区 */}
<div className="flex-1 grid grid-cols-12 gap-4 mt-4 min-h-0 overflow-hidden">
{/* 左栏 - 任务与流程区 (22%) */}
<div className="col-span-3 flex flex-col gap-4 min-h-0 overflow-y-auto">
{/* 任务信息卡 */}
<div className={`rounded-xl p-4 flex-shrink-0 border ${
isDark ? 'bg-slate-800/30 backdrop-blur-xl border-blue-800/30' : 'bg-white border-red-100 shadow-sm'
}`}>
<h3 className={`font-semibold text-sm mb-3 flex items-center gap-2 ${isDark ? 'text-white' : 'text-gray-900'}`}>
<FileText className={`w-4 h-4 ${isDark ? 'text-blue-400' : 'text-red-500'}`} />
任务信息
</h3>
<div className="space-y-2 text-sm">
<div className="flex items-center justify-between">
<span className={isDark ? 'text-slate-500' : 'text-gray-500'}>任务标题</span>
<span className={`text-right truncate max-w-[140px] ${isDark ? 'text-slate-300' : 'text-gray-700'}`}>五四青年节宣传活动策略</span>
</div>
<div className="flex items-center justify-between">
<span className={isDark ? 'text-slate-500' : 'text-gray-500'}>任务编号</span>
<span className={`text-xs ${isDark ? 'text-slate-400' : 'text-gray-400'}`}>TASK-0319-001</span>
</div>
<div className="flex items-center justify-between">
<span className={isDark ? 'text-slate-500' : 'text-gray-500'}>所属场景</span>
<span className={`text-xs ${isDark ? 'text-blue-400' : 'text-red-600'}`}>宣传策略生成</span>
</div>
<div className={`pt-2 border-t ${isDark ? 'border-blue-800/30' : 'border-red-100'}`}>
<div className="flex items-center justify-between text-xs">
<span className={`flex items-center gap-1 ${isDark ? 'text-slate-500' : 'text-gray-500'}`}>
<User className="w-3 h-3" /> 张策略
</span>
<span className={`flex items-center gap-1 ${isDark ? 'text-slate-500' : 'text-gray-500'}`}>
<Clock className="w-3 h-3" /> 2026-03-19
</span>
</div>
</div>
</div>
</div>
{/* 流程节点区 */}
<div className={`rounded-xl p-4 flex-shrink-0 border ${
isDark ? 'bg-slate-800/30 backdrop-blur-xl border-blue-800/30' : 'bg-white border-red-100 shadow-sm'
}`}>
<h3 className={`font-semibold text-sm mb-3 flex items-center gap-2 ${isDark ? 'text-white' : 'text-gray-900'}`}>
<Bot className={`w-4 h-4 ${isDark ? 'text-cyan-400' : 'text-red-500'}`} />
流程节点
</h3>
<div className="space-y-1.5">
{phases.map((phase) => (
<button
key={phase.id}
onClick={() => setCurrentPhase(phase.id)}
className={`w-full flex items-center gap-2 p-2 rounded-lg transition-all text-left border ${
phase.status === 'active'
? isDark
? 'bg-blue-500/20 border-blue-500/30'
: 'bg-red-50 border-red-200'
: phase.status === 'completed'
? isDark
? 'bg-slate-900/50 hover:bg-slate-800/50'
: 'bg-gray-50 hover:bg-gray-100'
: isDark
? 'bg-slate-900/30 opacity-50'
: 'bg-gray-50 opacity-50'
}`}
>
<div className={`w-5 h-5 rounded-full flex items-center justify-center text-xs font-bold flex-shrink-0 ${
phase.status === 'completed'
? isDark ? 'bg-green-500 text-white' : 'bg-green-500 text-white'
: phase.status === 'active'
? isDark ? 'bg-blue-500 text-white' : 'bg-blue-500 text-white'
: isDark ? 'bg-slate-700 text-slate-400' : 'bg-gray-200 text-gray-500'
}`}>
{phase.id}
</div>
<div className="flex-1 min-w-0">
<p className={`text-xs font-medium truncate ${
phase.status === 'active' ? (isDark ? 'text-white' : 'text-gray-900') : (isDark ? 'text-slate-400' : 'text-gray-500')
}`}>
{phase.name}
</p>
<p className={`text-[10px] truncate ${isDark ? 'text-slate-500' : 'text-gray-400'}`}>{phase.agent}</p>
</div>
<span className={`w-1.5 h-1.5 rounded-full flex-shrink-0 ${
phase.status === 'completed' ? (isDark ? 'bg-green-400' : 'bg-green-500') :
phase.status === 'active' ? (isDark ? 'bg-blue-400' : 'bg-blue-500') :
(isDark ? 'bg-slate-600' : 'bg-gray-300')
}`} />
</button>
))}
</div>
</div>
{/* 快捷操作卡 */}
<div className={`rounded-xl p-4 flex-shrink-0 border ${
isDark ? 'bg-slate-800/30 backdrop-blur-xl border-blue-800/30' : 'bg-white border-red-100 shadow-sm'
}`}>
<h3 className={`font-semibold text-sm mb-3 flex items-center gap-2 ${isDark ? 'text-white' : 'text-gray-900'}`}>
<Zap className={`w-4 h-4 ${isDark ? 'text-yellow-400' : 'text-red-500'}`} />
快捷操作
</h3>
<div className="space-y-2">
<button className={`w-full flex items-center justify-center gap-2 px-3 py-2 rounded-lg text-sm transition-colors border ${
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-200 text-gray-700'
}`}>
<RefreshCw className="w-4 h-4" />
重新运行当前节点
</button>
<button className={`w-full flex items-center justify-center gap-2 px-3 py-2 rounded-lg text-sm transition-colors border ${
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-200 text-gray-700'
}`}>
<RotateCcw className="w-4 h-4" />
发起回退
</button>
<button className={`w-full flex items-center justify-center gap-2 px-3 py-2 rounded-lg text-sm transition-colors border ${
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-200 text-gray-700'
}`}>
<FileInput className="w-4 h-4" />
查看日志
</button>
<button
onClick={() => setShowHumanIntervention(true)}
className={`w-full flex items-center justify-center gap-2 px-3 py-2 rounded-lg text-sm transition-colors border ${
isDark
? 'bg-purple-500/20 hover:bg-purple-500/30 border-purple-500/30 text-purple-400'
: 'bg-purple-100 hover:bg-purple-200 border-purple-200 text-purple-600'
}`}
>
<UserCheck className="w-4 h-4" />
人工介入
</button>
</div>
</div>
</div>
{/* 中栏 - 讨论区 (47%) */}
<div className="col-span-6 flex flex-col gap-4 min-h-0">
{/* 当前议题卡 */}
<div className={`rounded-xl p-4 flex-shrink-0 border ${
isDark ? 'bg-slate-800/30 backdrop-blur-xl border-blue-800/30' : 'bg-white border-red-100 shadow-sm'
}`}>
<div className="flex items-center justify-between">
<div className="flex items-center gap-3">
<div className={`w-8 h-8 rounded-lg flex items-center justify-center ${
isDark ? 'bg-cyan-500/20' : 'bg-red-100'
}`}>
<MessageSquare className={`w-4 h-4 ${isDark ? 'text-cyan-400' : 'text-red-500'}`} />
</div>
<div>
<p className={`text-xs ${isDark ? 'text-slate-400' : 'text-gray-500'}`}>当前议题</p>
<p className={`text-sm font-medium ${isDark ? 'text-white' : 'text-gray-900'}`}>明确目标受众的行为模式和转化路径</p>
</div>
</div>
<div className="flex items-center gap-2">
<span className={`px-2.5 py-1 rounded-full text-xs font-medium ${
isDark ? 'bg-cyan-500/20 text-cyan-400' : 'bg-red-100 text-red-600'
}`}>
BehaviorAgent
</span>
<button className={`px-2 py-1 rounded text-xs transition-colors border ${
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-200 text-gray-700'
}`}>
指定发言
</button>
<button className={`px-2 py-1 rounded text-xs transition-colors border ${
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-200 text-gray-700'
}`}>
结束本轮
</button>
</div>
</div>
<div className={`mt-3 p-2 rounded-lg text-xs ${isDark ? 'bg-slate-900/50' : 'bg-gray-50'}`}>
<span className={isDark ? 'text-slate-500' : 'text-gray-400'}>上游输入:</span>
<span className={isDark ? 'text-cyan-400' : 'text-red-600'}>AudienceAgent 已确认输出</span>
<span className={`mx-2 ${isDark ? 'text-slate-400' : 'text-gray-400'}`}>→</span>
<span className={isDark ? 'text-slate-300' : 'text-gray-700'}>核心受众已明确:18-25岁基层青年群体</span>
</div>
</div>
{/* 讨论消息流 */}
<div className={`flex-1 rounded-xl p-4 overflow-y-auto min-h-0 border ${
isDark ? 'bg-slate-800/30 backdrop-blur-xl border-blue-800/30' : 'bg-white border-red-100 shadow-sm'
}`}>
<h3 className={`font-semibold text-sm mb-4 flex items-center gap-2 ${isDark ? 'text-white' : 'text-gray-900'}`}>
<Bot className={`w-4 h-4 ${isDark ? 'text-purple-400' : 'text-red-500'}`} />
讨论消息流
</h3>
<div className="space-y-4">
{discussionCards.map((card) => (
<div
key={card.id}
className={`p-4 rounded-xl border ${
card.releaseStatus === 'passed'
? isDark
? 'bg-slate-900/50 border-green-500/30'
: 'bg-green-50 border-green-200'
: card.releaseStatus === 'pending'
? isDark
? 'bg-blue-500/10 border-blue-500/30'
: 'bg-blue-50 border-blue-200'
: isDark
? 'bg-red-500/10 border-red-500/30'
: 'bg-red-50 border-red-200'
}`}
>
<div className="flex items-start justify-between mb-3">
<div className="flex items-center gap-2">
<div className={`w-8 h-8 rounded-lg flex items-center justify-center ${
isDark ? 'bg-purple-500/20' : 'bg-red-100'
}`}>
<Bot className={`w-4 h-4 ${isDark ? 'text-purple-400' : 'text-red-500'}`} />
</div>
<div>
<div className="flex items-center gap-2">
<p className={`text-sm font-medium ${isDark ? 'text-white' : 'text-gray-900'}`}>{card.agent}</p>
<span className={`px-1.5 py-0.5 rounded text-[10px] ${isDark ? 'bg-slate-700 text-slate-400' : 'bg-gray-100 text-gray-500'}`}>
{card.type === 'judgment' ? '独立判断' : '回应'}
</span>
</div>
<p className={`text-xs ${isDark ? 'text-slate-500' : 'text-gray-400'}`}>{card.phase} · {card.time}</p>
</div>
</div>
<span className={`px-2 py-1 rounded-full text-xs font-medium flex items-center gap-1 ${
card.releaseStatus === 'passed'
? isDark
? 'bg-green-500/20 text-green-400'
: 'bg-green-100 text-green-600'
: card.releaseStatus === 'pending'
? isDark
? 'bg-yellow-500/20 text-yellow-400'
: 'bg-yellow-100 text-yellow-600'
: isDark
? 'bg-red-500/20 text-red-400'
: 'bg-red-100 text-red-600'
}`}>
{card.releaseStatus === 'passed' ? (
<><CheckCircle className="w-3 h-3" /> 已放行</>
) : card.releaseStatus === 'pending' ? (
<><Clock className="w-3 h-3" /> 待放行</>
) : (
<><AlertTriangle className="w-3 h-3" /> 未通过</>
)}
</span>
</div>
<div className="mb-3">
<p className={`text-xs mb-1 ${isDark ? 'text-slate-400' : 'text-gray-500'}`}>核心观点</p>
<p className={`text-sm ${isDark ? 'text-white' : 'text-gray-900'}`}>{card.coreJudgment}</p>
</div>
<div className={`mb-3 p-3 rounded-lg ${isDark ? 'bg-slate-800/50' : 'bg-gray-50'}`}>
<p className={`text-xs mb-2 ${isDark ? 'text-slate-500' : 'text-gray-400'}`}>输出字段摘要</p>
<div className="space-y-1 text-xs">
{Object.entries(card.outputFields).map(([key, value]) => (
<div key={key} className="flex items-start gap-2">
<span className={`font-mono ${isDark ? 'text-cyan-400' : 'text-red-600'}`}>{key}:</span>
<span className={isDark ? 'text-slate-300' : 'text-gray-700'}>
{Array.isArray(value) ? value.join(', ') : value}
</span>
</div>
))}
</div>
</div>
{card.riskWarnings.length > 0 && (
<div className={`mb-3 p-2 rounded-lg border ${
isDark ? 'bg-amber-500/10 border-amber-500/30' : 'bg-yellow-50 border-yellow-200'
}`}>
<p className={`text-xs font-medium flex items-center gap-1 ${
isDark ? 'text-amber-400' : 'text-yellow-600'
}`}>
<AlertTriangle className="w-3 h-3" /> 风险提示
</p>
<p className={`text-xs mt-1 ${isDark ? 'text-slate-300' : 'text-gray-700'}`}>{card.riskWarnings[0]}</p>
</div>
)}
<div className={`flex items-center gap-2 pt-2 border-t ${isDark ? 'border-blue-800/30' : 'border-gray-200'}`}>
<button className={`px-2.5 py-1.5 rounded text-xs transition-colors ${
isDark
? 'bg-green-600/50 hover:bg-green-600 text-white'
: 'bg-green-600 hover:bg-green-500 text-white'
}`}>
采纳
</button>
<button className={`px-2.5 py-1.5 rounded text-xs transition-colors border ${
isDark
? 'bg-yellow-500/20 hover:bg-yellow-500/30 border-yellow-500/30 text-yellow-400'
: 'bg-yellow-100 hover:bg-yellow-200 border-yellow-200 text-yellow-600'
}`}>
待确认
</button>
<button className={`px-2.5 py-1.5 rounded text-xs transition-colors border ${
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-200 text-gray-700'
}`}>
引用追问
</button>
<button className={`px-2.5 py-1.5 rounded text-xs transition-colors border ${
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-200 text-gray-700'
}`}>
写入策略链
</button>
</div>
</div>
))}
{/* 系统摘要卡 */}
<div className={`p-4 rounded-xl border ${
isDark ? 'bg-blue-500/10 border-blue-500/30' : 'bg-blue-50 border-blue-200'
}`}>
<div className="flex items-center gap-2 mb-3">
<div className={`w-6 h-6 rounded flex items-center justify-center ${
isDark ? 'bg-blue-500/20' : 'bg-blue-100'
}`}>
<Lightbulb className={`w-3 h-3 ${isDark ? 'text-blue-400' : 'text-blue-500'}`} />
</div>
<p className={`text-sm font-medium ${isDark ? 'text-blue-400' : 'text-blue-600'}`}>系统摘要</p>
</div>
<div className="space-y-2 text-sm">
<div>
<p className={`text-xs mb-1 ${isDark ? 'text-slate-400' : 'text-gray-500'}`}>已形成结论:</p>
<ul className={`text-xs space-y-0.5 list-disc list-inside ${isDark ? 'text-slate-300' : 'text-gray-700'}`}>
<li>核心受众明确为18-25岁基层青年</li>
<li>目标行为建议拆分为参与和传播两层</li>
</ul>
</div>
<div>
<p className={`text-xs mb-1 ${isDark ? 'text-slate-400' : 'text-gray-500'}`}>待确认:</p>
<ul className={`text-xs space-y-0.5 list-disc list-inside ${isDark ? 'text-yellow-400' : 'text-yellow-600'}`}>
<li>UGC创作是否纳入核心行为?</li>
</ul>
</div>
<div className={`pt-2 border-t ${isDark ? 'border-blue-800/30' : 'border-blue-200'}`}>
<p className={`text-xs ${isDark ? 'text-slate-400' : 'text-gray-500'}`}>建议下一步:</p>
<p className={`text-xs ${isDark ? 'text-cyan-400' : 'text-red-600'}`}>邀请 DriverAgent 分析驱动因素</p>
</div>
</div>
<div className="flex items-center gap-2 mt-3">
<button className={`px-3 py-1.5 rounded text-xs transition-colors ${
isDark
? 'bg-blue-600 hover:bg-blue-500 text-white'
: 'bg-blue-600 hover:bg-blue-500 text-white shadow-md'
}`}>
推进下一步
</button>
<button className={`px-3 py-1.5 rounded text-xs transition-colors border ${
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-200 text-gray-700'
}`}>
写入待确认
</button>
</div>
</div>
</div>
</div>
</div>
{/* 右栏 - 策略收敛区 (28%) */}
<div className="col-span-3 flex flex-col gap-4 min-h-0 overflow-y-auto">
{/* 策略链卡 */}
<div className={`rounded-xl p-4 flex-shrink-0 border ${
isDark
? 'bg-gradient-to-br from-blue-600/20 to-cyan-600/20 backdrop-blur-xl border-blue-500/30'
: 'bg-gradient-to-br from-red-50 to-red-100 border-red-200'
}`}>
<div className="flex items-center justify-between mb-3">
<h3 className={`font-semibold text-sm flex items-center gap-2 ${isDark ? 'text-white' : 'text-gray-900'}`}>
<Lightbulb className={`w-4 h-4 ${isDark ? 'text-yellow-400' : 'text-red-500'}`} />
策略链
</h3>
<div className="flex items-center gap-1">
<button className={`p-1 rounded transition-colors ${isDark ? 'hover:bg-slate-700/50' : 'hover:bg-red-50'}`} title="复制">
<FileText className={`w-3.5 h-3.5 ${isDark ? 'text-slate-400' : 'text-gray-400'}`} />
</button>
<button className={`p-1 rounded transition-colors ${isDark ? 'hover:bg-slate-700/50' : 'hover:bg-red-50'}`} title="编辑">
<RefreshCw className={`w-3.5 h-3.5 ${isDark ? 'text-slate-400' : 'text-gray-400'}`} />
</button>
</div>
</div>
<div className={`p-3 rounded-lg border ${
isDark ? 'bg-slate-900/50 border-blue-500/20' : 'bg-white border-red-100'
}`}>
<p className={`text-xs leading-relaxed ${isDark ? 'text-slate-300' : 'text-gray-700'}`}>
面向<span className={`font-medium ${isDark ? 'text-cyan-400' : 'text-red-600'}`}>【18-25岁基层青年】</span>,
围绕其<span className={`font-medium ${isDark ? 'text-yellow-400' : 'text-red-600'}`}>【社交认同与自我表达】</span>驱动,
传播<span className={`font-medium ${isDark ? 'text-purple-400' : 'text-red-600'}`}>【真实、有态度的青年故事】</span>叙事,
促使其产生<span className={`font-medium ${isDark ? 'text-green-400' : 'text-red-600'}`}>【主动参与互动并生成UGC内容】</span>行为,
从而实现<span className={`font-medium ${isDark ? 'text-blue-400' : 'text-red-600'}`}>【提升品牌在Z世代用户中的认知度】</span>目标。
</p>
</div>
</div>
{/* 逻辑链一致性校验 */}
<div className={`rounded-xl p-4 flex-shrink-0 border ${
isDark ? 'bg-slate-800/30 backdrop-blur-xl border-blue-800/30' : 'bg-white border-red-100 shadow-sm'
}`}>
<div className="flex items-center justify-between mb-3">
<h3 className={`font-semibold text-sm flex items-center gap-2 ${isDark ? 'text-white' : 'text-gray-900'}`}>
<Shield className={`w-4 h-4 ${isDark ? 'text-green-400' : 'text-red-500'}`} />
逻辑链一致性
</h3>
<span className={`px-2 py-0.5 rounded text-xs ${
isDark ? 'bg-green-500/20 text-green-400' : 'bg-green-100 text-green-600'
}`}>
3/4 通过
</span>
</div>
<div className="space-y-1.5">
{logicChainChecks.map((check) => (
<div
key={check.id}
className={`p-2 rounded-lg border text-xs ${
check.status === 'passed'
? isDark
? 'bg-green-500/10 border-green-500/30'
: 'bg-green-50 border-green-200'
: check.status === 'warning'
? isDark
? 'bg-yellow-500/10 border-yellow-500/30'
: 'bg-yellow-50 border-yellow-200'
: isDark
? 'bg-red-500/10 border-red-500/30'
: 'bg-red-50 border-red-200'
}`}
>
<div className="flex items-center justify-between">
<span className={`font-medium ${
check.status === 'passed'
? isDark ? 'text-green-400' : 'text-green-600'
: check.status === 'warning'
? isDark ? 'text-yellow-400' : 'text-yellow-600'
: isDark ? 'text-red-400' : 'text-red-600'
}`}>
{check.label}
</span>
{check.status === 'passed' ? (
<CheckCircle2 className={`w-3.5 h-3.5 ${isDark ? 'text-green-400' : 'text-green-500'}`} />
) : check.status === 'warning' ? (
<AlertCircle className={`w-3.5 h-3.5 ${isDark ? 'text-yellow-400' : 'text-yellow-500'}`} />
) : (
<XCircle className={`w-3.5 h-3.5 ${isDark ? 'text-red-400' : 'text-red-500'}`} />
)}
</div>
</div>
))}
</div>
</div>
{/* 已采纳观点 */}
<div className={`rounded-xl p-4 flex-shrink-0 border ${
isDark ? 'bg-slate-800/30 backdrop-blur-xl border-blue-800/30' : 'bg-white border-red-100 shadow-sm'
}`}>
<h3 className={`font-semibold text-sm mb-3 flex items-center gap-2 ${isDark ? 'text-white' : 'text-gray-900'}`}>
<CheckCircle className={`w-4 h-4 ${isDark ? 'text-green-400' : 'text-red-500'}`} />
已采纳观点
</h3>
<div className="space-y-2">
{[
{ agent: 'GoalAgent', opinion: '主目标是提升认知度与好感度' },
{ agent: 'AudienceAgent', opinion: '核心受众为18-25岁基层青年' },
{ agent: 'BehaviorAgent', opinion: '目标行为应拆为参与和传播' },
].map((item, index) => (
<div key={index} className={`p-2 rounded-lg border ${
isDark ? 'bg-slate-900/50 border-green-500/20' : 'bg-green-50 border-green-200'
}`}>
<p className={`text-xs font-medium mb-0.5 ${isDark ? 'text-green-400' : 'text-green-600'}`}>{item.agent}</p>
<p className={`text-xs ${isDark ? 'text-slate-300' : 'text-gray-700'}`}>{item.opinion}</p>
</div>
))}
</div>
</div>
{/* 待确认与分歧 */}
<div className={`rounded-xl p-4 flex-shrink-0 border ${
isDark ? 'bg-slate-800/30 backdrop-blur-xl border-blue-800/30' : 'bg-white border-red-100 shadow-sm'
}`}>
<div className="flex items-center justify-between mb-3">
<h3 className={`font-semibold text-sm flex items-center gap-2 ${isDark ? 'text-white' : 'text-gray-900'}`}>
<AlertTriangle className={`w-4 h-4 ${isDark ? 'text-amber-400' : 'text-red-500'}`} />
待确认与分歧
</h3>
<span className={`px-2 py-0.5 rounded text-xs ${
isDark ? 'bg-amber-500/20 text-amber-400' : 'bg-yellow-100 text-yellow-600'
}`}>
{pendingQuestions.length} 项
</span>
</div>
<div className="space-y-2">
{pendingQuestions.map((question) => (
<div
key={question.id}
className={`p-2 rounded-lg border ${
question.priority === 'high'
? isDark
? 'bg-red-500/10 border-red-500/30'
: 'bg-red-50 border-red-200'
: isDark
? 'bg-amber-500/10 border-amber-500/30'
: 'bg-yellow-50 border-yellow-200'
}`}
>
<p className={`text-xs font-medium ${
question.priority === 'high' ? (isDark ? 'text-red-400' : 'text-red-600') : (isDark ? 'text-amber-400' : 'text-yellow-600')
}`}>
{question.title}
</p>
<p className={`text-xs mt-0.5 ${isDark ? 'text-slate-400' : 'text-gray-500'}`}>{question.description}</p>
<button className={`mt-1 text-xs flex items-center gap-1 ${
isDark ? 'text-blue-400 hover:text-blue-300' : 'text-blue-500 hover:text-blue-600'
}`}>
<UserCheck className="w-3 h-3" />
点名分析
</button>
</div>
))}
</div>
</div>
</div>
</div>
{/* 底部:固定输入区 */}
<div className={`mt-4 rounded-xl p-4 flex-shrink-0 border ${
isDark ? 'bg-slate-800/30 backdrop-blur-xl border-blue-800/30' : 'bg-white border-red-100 shadow-sm'
}`}>
<div className="flex items-center gap-3">
{/* 发送对象选择 */}
<select
value={sendTarget}
onChange={(e) => setSendTarget(e.target.value)}
className={`px-3 py-2 rounded-lg text-sm focus:outline-none ${
isDark
? 'bg-slate-900/50 border border-blue-800/30 text-white'
: 'bg-white border border-gray-200 text-gray-700'
}`}
>
<option value="current">当前智能体</option>
<option value="all">全部智能体</option>
<option value="host">主持人</option>
</select>
{/* 输入类型选择 */}
<select
value={inputType}
onChange={(e) => setInputType(e.target.value)}
className={`px-3 py-2 rounded-lg text-sm focus:outline-none ${
isDark
? 'bg-slate-900/50 border border-blue-800/30 text-white'
: 'bg-white border border-gray-200 text-gray-700'
}`}
>
<option value="question">提问</option>
<option value="instruction">指令</option>
<option value="judgment">人工判断</option>
<option value="note">批注</option>
</select>
{/* 主输入框 */}
<input
type="text"
value={inputMessage}
onChange={(e) => setInputMessage(e.target.value)}
placeholder="输入问题、指令、人工判断或批注..."
className={`flex-1 px-4 py-2 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-red-500/20 ${
isDark
? 'bg-slate-900/50 border border-blue-800/30 text-white placeholder-slate-500'
: 'bg-white border border-gray-200 text-gray-900 placeholder-gray-400'
}`}
/>
{/* 发送按钮 */}
<button className={`flex items-center gap-2 px-4 py-2 rounded-lg text-sm font-medium transition-colors ${
isDark
? 'bg-blue-600 hover:bg-blue-500 text-white'
: 'bg-red-600 hover:bg-red-500 text-white shadow-md'
}`}>
<Send className="w-4 h-4" />
发送
</button>
</div>
{/* 第二行快捷操作 */}
<div className="flex items-center gap-4 mt-3">
<button className={`flex items-center gap-1.5 px-2 py-1 rounded text-xs transition-colors border ${
isDark
? 'bg-slate-700/50 hover:bg-slate-600/50 border-blue-800/30 text-slate-400'
: 'bg-gray-100 hover:bg-gray-200 border-gray-200 text-gray-500'
}`}>
<AtSign className="w-3 h-3" />
@智能体
</button>
<button className={`flex items-center gap-1.5 px-2 py-1 rounded text-xs transition-colors border ${
isDark
? 'bg-slate-700/50 hover:bg-slate-600/50 border-blue-800/30 text-slate-400'
: 'bg-gray-100 hover:bg-gray-200 border-gray-200 text-gray-500'
}`}>
<FileInput className="w-3 h-3" />
引用消息
</button>
<button className={`flex items-center gap-1.5 px-2 py-1 rounded text-xs transition-colors border ${
isDark
? 'bg-slate-700/50 hover:bg-slate-600/50 border-blue-800/30 text-slate-400'
: 'bg-gray-100 hover:bg-gray-200 border-gray-200 text-gray-500'
}`}>
<Lightbulb className="w-3 h-3" />
生成摘要
</button>
<button className={`flex items-center gap-1.5 px-2 py-1 rounded text-xs transition-colors border ${
isDark
? 'bg-slate-700/50 hover:bg-slate-600/50 border-blue-800/30 text-slate-400'
: 'bg-gray-100 hover:bg-gray-200 border-gray-200 text-gray-500'
}`}>
<Plus className="w-3 h-3" />
写入整合区
</button>
</div>
</div>
{/* 人工干预弹窗 */}
{showHumanIntervention && (
<div className="fixed inset-0 bg-black/60 backdrop-blur-sm flex items-center justify-center z-50">
<div className={`rounded-2xl p-6 w-full max-w-lg border ${
isDark ? 'bg-slate-800 border-blue-800/50' : 'bg-white border-red-200'
}`}>
<div className="flex items-center justify-between mb-6">
<h3 className={`font-semibold text-lg flex items-center gap-2 ${isDark ? 'text-white' : 'text-gray-900'}`}>
<UserCheck className={`w-5 h-5 ${isDark ? 'text-purple-400' : 'text-red-500'}`} />
人工干预
</h3>
<button
onClick={() => setShowHumanIntervention(false)}
className={`p-2 rounded-lg transition-colors ${isDark ? 'hover:bg-slate-700' : 'hover:bg-gray-100'}`}
>
<XCircle className={`w-5 h-5 ${isDark ? 'text-slate-400' : 'text-gray-400'}`} />
</button>
</div>
<div className="space-y-4">
<div>
<label className={`block text-sm mb-2 ${isDark ? 'text-slate-400' : 'text-gray-500'}`}>干预类型</label>
<div className="grid grid-cols-2 gap-3">
{[
{ value: 'correct', label: '人工修正', icon: RefreshCw },
{ value: 'approve', label: '提前放行', icon: CheckCircle2 },
{ value: 'override', label: '强制覆盖', icon: Zap },
{ value: 'reject', label: '终止本轮', icon: XCircle },
].map((type) => (
<button
key={type.value}
className={`flex items-center gap-2 p-3 rounded-lg transition-colors border ${
isDark
? 'bg-slate-900/50 hover:bg-slate-700/50 border-blue-800/30 text-slate-300'
: 'bg-gray-50 hover:bg-gray-100 border-gray-200 text-gray-700'
}`}
>
<type.icon className={`w-4 h-4 ${isDark ? 'text-blue-400' : 'text-red-500'}`} />
<span className="text-sm">{type.label}</span>
</button>
))}
</div>
</div>
<div>
<label className={`block text-sm mb-2 ${isDark ? 'text-slate-400' : 'text-gray-500'}`}>目标字段</label>
<select className={`w-full px-4 py-2.5 rounded-lg text-sm ${
isDark
? 'bg-slate-900/50 border border-blue-800/30 text-white'
: 'bg-white border border-gray-200 text-gray-700'
}`}>
<option value="">请选择要干预的字段</option>
<option value="audience">受众细分</option>
<option value="behavior">目标行为</option>
<option value="driver">核心驱动</option>
<option value="narrative">叙事策略</option>
</select>
</div>
<div>
<label className={`block text-sm mb-2 ${isDark ? 'text-slate-400' : 'text-gray-500'}`}>干预内容</label>
<textarea
rows={4}
className={`w-full px-4 py-2.5 rounded-lg text-sm resize-none ${
isDark
? 'bg-slate-900/50 border border-blue-800/30 text-white placeholder-slate-500'
: 'bg-white border border-gray-200 text-gray-900 placeholder-gray-400'
}`}
placeholder="请输入人工干预的具体内容或修正意见..."
/>
</div>
<div className="flex gap-3 pt-2">
<button
onClick={() => setShowHumanIntervention(false)}
className={`flex-1 px-4 py-2.5 rounded-lg text-sm transition-colors border ${
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-200 text-gray-700'
}`}
>
取消
</button>
<button className={`flex-1 px-4 py-2.5 rounded-lg text-sm transition-colors ${
isDark
? 'bg-purple-600 hover:bg-purple-500 text-white'
: 'bg-red-600 hover:bg-red-500 text-white shadow-md'
}`}>
确认干预
</button>
</div>
</div>
</div>
</div>
)}
</div>
);
};
export default TaskWorkspace;