import React, { useEffect, useRef, useState } from 'react'; import { Plus, Search, Eye, Play, Pause, Clock, User, ChevronRight, Filter, FileText, AlertTriangle, CheckCircle, XCircle, MoreHorizontal, Edit, Download, Bot, Users, Workflow, X, ArrowRight, Target, Layers, } from 'lucide-react'; import { useTheme } from '@/contexts/ThemeContext'; import { PageType } from '@/components/Sidebar'; // 导入请求服务,用于与后端 API 交互 import { requestCrudService } from '@/service/request-axios-service'; import { KanbanColumn } from './KanbanColumn'; import { TaskListItem } from '@/pages/TaskManagement'; import { DateRangePicker, DateRangePickerProps, DateRangeValue, Loading } from 'tdesign-react'; import { useNavigate } from 'react-router-dom'; import dayjs from 'dayjs'; import { useChatContext } from '@/contexts/ChatContext'; interface TaskListPageProps { title: string; category: string; subCategory: string; onNavigate: (page: PageType) => void; } type TaskType = 'single' | 'consultation' | 'scene' | 'multi-agent' | 'task-search'; type TaskStatus = 'draft' | 'pending' | 'running' | 'paused' | 'blocked' | 'completed'; type ColumnType = 'unanalyzed' | 'analyzing' | 'completed'; interface Task { id: string; name: string; type: TaskType; status: TaskStatus; agent?: string; scene?: string; participants?: string[]; currentPhase?: string; currentRound?: number; summary?: string; creator: string; createTime: string; updateTime: string; column: ColumnType; } interface stateItem { startTime: string, endTime: string, task: TaskListItem, } const service = requestCrudService; const zncmUrl = import.meta.env.VITE_API_BASE_URL || ''; const TaskAnalyzes: React.FC = ({ title, category, subCategory, onNavigate }) => { const { theme } = useTheme(); const { setStartConfig } = useChatContext(); const router = useNavigate(); const isDark = theme === 'dark'; // 主题颜色变量 const cardBg = isDark ? 'bg-slate-800/30' : 'bg-white'; const cardBorder = isDark ? 'border-blue-800/30' : 'border-red-100'; 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-400'; const inputBg = isDark ? 'bg-slate-900/50' : 'bg-white'; // 生成模拟数据 const [tasks] = useState([ // 未分析列 { id: '2026-0320-001', name: '端午节品牌传播方案', type: 'scene', scene: '宣传策略生成', status: 'draft', column: 'unanalyzed', summary: '针对端午节品牌活动制定完整传播策略方案', creator: '李策划', createTime: '2026-03-20 10:00', updateTime: '2026-03-20 10:00', }, { id: '2026-0320-002', name: '新品上市用户调研', type: 'single', agent: 'AudienceAgent', status: 'pending', column: 'unanalyzed', summary: '对新品目标用户进行画像分析', creator: '王运营', createTime: '2026-03-20 09:30', updateTime: '2026-03-20 09:30', }, // 分析中列 { id: '2026-0319-001', name: '五四青年节宣传活动策略', type: 'scene', scene: '宣传策略生成', status: 'running', currentPhase: '行为分析', column: 'analyzing', summary: '正在按场景模板执行目标、受众、行为、叙事等分析...', creator: '张策略', createTime: '2026-03-19 10:30', updateTime: '2026-03-20 09:45', }, { id: '2026-0319-002', name: '青年传播方向会商分析', type: 'consultation', participants: ['GoalAgent', 'AudienceAgent', 'NarrativeAgent'], status: 'running', currentRound: 2, column: 'analyzing', summary: '围绕宣传方向、叙事方式和受众切入点开展多视角会商...', creator: '王策划', createTime: '2026-03-19 14:00', updateTime: '2026-03-20 09:00', }, { id: '2026-0318-001', name: '年度品牌升级方案推演', type: 'scene', scene: '宣传方案推演', status: 'paused', currentPhase: '叙事分析', column: 'analyzing', summary: '任务已暂停,等待人工介入确认叙事方向', creator: '王策划', createTime: '2026-03-18 14:00', updateTime: '2026-03-20 08:30', }, // 已完成列 { id: '2026-0318-002', name: '核心受众画像分析', type: 'single', agent: 'AudienceAgent', status: 'completed', column: 'completed', summary: '已完成目标受众识别、关切提炼和阻力分析', creator: '赵运营', createTime: '2026-03-18 09:00', updateTime: '2026-03-18 16:30', }, { id: '2026-0319-003', name: '五四青年节宣传策略', type: 'scene', scene: '宣传策略生成', status: 'completed', column: 'completed', summary: '已完成宣传策略方案生成', creator: '张策略', createTime: '2026-03-19 10:00', updateTime: '2026-03-19 18:00', }, { id: '2026-0319-004', name: '青年品牌传播路径会商', type: 'consultation', participants: ['GoalAgent', 'NarrativeAgent', 'RiskAgent'], status: 'completed', column: 'completed', summary: '已完成多智能体会商,形成结论与分歧报告', creator: '王策划', createTime: '2026-03-19 14:30', updateTime: '2026-03-19 17:00', }, ]); const [searchQuery, setSearchQuery] = useState(''); const [modeFilter, setModeFilter] = useState('all'); const [showAnalysisModal, setShowAnalysisModal] = useState(false); const [selectedTaskForAnalysis, setSelectedTaskForAnalysis] = useState(null); const [unanalyzedTotal, setUnanalyzedTotal] = useState(0); // 未分析 const [runningTotal, setRunningTotal] = useState(0); // 分析中 const [completedTotal, setCompletedTotal] = useState(0); // 已完成 const [unanalyzedList, setUnanalyzedList] = useState([]); // 未分析 const [runningList, setRunningList] = useState([]); // 分析中 const [completedList, setCompletedList] = useState([]); // 已完成 const [unanalyzedLoading, setUnanalyzedLoading] = useState(false); // 未分析 const [runningLoading, setRunningLoading] = useState(false); // 分析中 const [completedLoading, setCompletedLoading] = useState(false); // 已完成 const [presets] = useState({ 最近7天: [dayjs().subtract(6, 'day').toDate(), dayjs().toDate()], 最近3天: [dayjs().subtract(2, 'day').toDate(), dayjs().toDate()], 今天: [dayjs().toDate(), dayjs().toDate()], }); const [range, setRange] = useState([]); const state = useRef({ startTime: '', endTime: '', task: {} as TaskListItem, }) // 时间日期选择器查询 const setRangeChange = async (val) => { setRange(val); console.log('时间日期', val); state.current.startTime = ''; state.current.endTime = ''; if (val.length > 0) { state.current.startTime = val[0]; state.current.endTime = val[1]; } await taskDataChange(); } // 获取任务类型配置 const getTypeConfig = (type: TaskType) => { if (isDark) { switch (type) { case 'single': return { label: '单智能体', color: 'bg-cyan-500/20 text-cyan-400', icon: Bot }; case 'scene': return { label: '场景执行', color: 'bg-purple-500/20 text-purple-400', icon: Workflow }; case 'consultation': return { label: '多智能体会商', color: 'bg-orange-500/20 text-orange-400', icon: Users }; case 'multi-agent': return { label: '多智能体协同', color: 'bg-green-500/20 text-green-400', icon: Layers }; } } else { switch (type) { case 'single': return { label: '单智能体', color: 'bg-blue-100 text-blue-600', icon: Bot }; case 'scene': return { label: '场景执行', color: 'bg-purple-100 text-purple-600', icon: Workflow }; case 'consultation': return { label: '多智能体会商', color: 'bg-orange-100 text-orange-600', icon: Users }; case 'multi-agent': return { label: '多智能体协同', color: 'bg-green-100 text-green-600', icon: Layers }; } } }; // 获取状态配置 const getStatusConfig = (status: TaskStatus, column: ColumnType) => { if (column === 'unanalyzed') { switch (status) { case 'draft': return { label: '草稿', color: isDark ? 'bg-slate-500/20 text-slate-400' : 'bg-gray-100 text-gray-600' }; case 'pending': return { label: '待启动', color: isDark ? 'bg-slate-500/20 text-slate-400' : 'bg-gray-100 text-gray-600' }; default: return { label: '待配置', color: isDark ? 'bg-yellow-500/20 text-yellow-400' : 'bg-yellow-100 text-yellow-600' }; } } else if (column === 'analyzing') { switch (status) { case 'running': return { label: '运行中', color: isDark ? 'bg-blue-500/20 text-blue-400' : 'bg-red-100 text-red-600' }; case 'paused': return { label: '已暂停', color: isDark ? 'bg-yellow-500/20 text-yellow-400' : 'bg-yellow-100 text-yellow-600' }; case 'blocked': return { label: '阻塞中', color: isDark ? 'bg-red-500/20 text-red-400' : 'bg-orange-100 text-orange-600' }; default: return { label: '待处理', color: isDark ? 'bg-purple-500/20 text-purple-400' : 'bg-purple-100 text-purple-600' }; } } else { return { label: '已完成', color: isDark ? 'bg-green-500/20 text-green-400' : 'bg-green-100 text-green-600' }; } }; // 筛选任务 const filteredTasks = tasks.filter(task => { const matchesSearch = task.name.toLowerCase().includes(searchQuery.toLowerCase()) || task.id.toLowerCase().includes(searchQuery.toLowerCase()); const matchesMode = modeFilter === 'all' || task.type === modeFilter; return matchesSearch && matchesMode; }); const unanalyzedTasks = filteredTasks.filter(t => t.column === 'unanalyzed'); const analyzingTasks = filteredTasks.filter(t => t.column === 'analyzing'); const completedTasks = filteredTasks.filter(t => t.column === 'completed'); // 统计数据 const stats = { total: tasks.length, unanalyzed: unanalyzedTasks.length, analyzing: analyzingTasks.length, completed: completedTasks.length, }; // 处理开始分析按钮点击 const handleStartAnalysis = (task: TaskListItem) => { setSelectedTaskForAnalysis(task); state.current.task = task; setShowAnalysisModal(true); }; // 处理分析模式选择 const handleSelectAnalysisMode = (mode: TaskType) => { setShowAnalysisModal(false); console.log('mode', mode); if (mode === 'single') { onNavigate('task-single'); } else if (mode === 'scene') { onNavigate('task-scene'); } else if (mode === 'consultation') { console.log('state.current.task', state.current.task) const sceneItem = JSON.parse(state.current.task.scene); if (sceneItem.taskJson) { sceneItem.taskJson = JSON.parse(sceneItem.taskJson); setStartConfig({ ...sceneItem.taskJson, llm_preset_id: 'BAILING', consistency_mode: 'soft', phase_config: {diverge_rounds: 3}, task_context: state.current.task.overview }); router('/qa-center/mope-chat') } console.log('sceneItem', sceneItem); // onNavigate('task-consult-create'); // window.open(`http://ch1.b.uat.4.cn/mopeweb/#/mope?taskOverview=${state.current.task.overview}`) } else if (mode === 'multi-agent') { onNavigate('multi-agent-qa'); } else if (mode === 'task-search') { window.open(`https://ch1.b.uat.4.cn/web/#/task/item-aicoh/step-info-search?id=${state.current.task.id}`) } }; // 处理卡片点击 const handleTaskClick = (task: Task) => { if (task.column === 'completed') { if (task.type === 'consultation') { onNavigate('task-consult-result'); } else { onNavigate('strategy-result'); } } else if (task.column === 'analyzing') { if (task.type === 'scene') { onNavigate('task-scene'); } else if (task.type === 'consultation') { onNavigate('task-consult'); } else { onNavigate('task-single'); } } }; const taskListSearch = async (taskType: string, pageNum: number = 1, pageSize: number = 10) => { let taskStatus: number[] = [] if (taskType === 'unanalyzed') { // 未分析 taskStatus = [0, 10]; setUnanalyzedLoading(true); } else if (taskType === 'running') { // 分析中 taskStatus = [20]; setRunningLoading(true); } else if (taskType === 'completed') { // 已完成 taskStatus = [25, 30, 40, 60, 70, 80, 90, 100, 110]; setCompletedLoading(true); } const param = { content: searchQuery, pageNum: pageNum, pageSize: pageSize, taskStatus: taskStatus, startTime: state.current.startTime, endTime: state.current.endTime, taskDirection: '' } const res = await service.post(`${zncmUrl}/task/cop-tasks`, param); console.log('任务列表', res); const result = res.data; result.records.forEach((item: TaskListItem) => { item.column = taskType; if (!item.taskLevel) item.taskLevel = 1; }) if (taskType === 'unanalyzed') { setUnanalyzedLoading(false); setUnanalyzedTotal(result.total); setUnanalyzedList(result.records); } else if (taskType === 'running') { setRunningLoading(false); setRunningTotal(result.total); setRunningList(result.records); } else if (taskType === 'completed') { setCompletedLoading(false); setCompletedTotal(result.total); setCompletedList(result.records); } } /** * 页码变化时的回调函数 * 当用户切换页码时触发,更新页码并重新获取数据 * @param value - 新的页码值 */ const pageIndexChange = async (type: string, pageIndex: number) => { // 更新 ref 中存储的页码值 // 更新页码状态,触发组件重新渲染 await taskListSearch(type, pageIndex); } const taskDataChange = async (pageNum: number = 1, pageSize: number = 10) => { taskListSearch('unanalyzed', pageNum, pageSize); taskListSearch('running', pageNum, pageSize); taskListSearch('completed', pageNum, pageSize); } // 回车处理 const handleKeyDown = async (e) => { if ((e.metaKey || e.ctrlKey || e.shiftKey) && e.key === "Enter") { e.preventDefault(); } else if (e.keyCode === 13) { e.preventDefault(); await taskDataChange(); } else if (e.key === "/") { e.preventDefault(); } }; useEffect(() => { taskDataChange(); }, []); // 渲染看板列 return (
{/* 顶部工具栏 */}
{category} / {subCategory}

任务中心

{/* 搜索和筛选 */}
setSearchQuery(e.target.value)} onKeyDown={(e) => handleKeyDown(e)} className={`w-full pl-10 pr-4 py-2 border rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-red-500/20 transition-colors ${inputBg} ${cardBorder} ${textPrimary} placeholder:${textMuted}`} />
{/* */} {/* */} setRangeChange(val)} enableTimePicker={true} clearable />
{/* 统计概览栏 */}
{/* 看板区 */}
{/* 选择分析模式弹窗 */} {showAnalysisModal && selectedTaskForAnalysis && (
setShowAnalysisModal(false)}>
e.stopPropagation()} >

选择分析模式

为任务「{selectedTaskForAnalysis.taskName}」选择分析方式

{/* 单智能体分析 */} {/* */} {/* 多智能体协同分析 */} {/* */} {/* 多智能体会商 */} {/* 场景执行 */} {/* */}
)}
); }; export default TaskAnalyzes;