diff --git a/src/frontend/src/pages/Briefing.tsx b/src/frontend/src/pages/Briefing.tsx new file mode 100644 index 0000000..d89f1b1 --- /dev/null +++ b/src/frontend/src/pages/Briefing.tsx @@ -0,0 +1,110 @@ +// AI Briefing 页面 + +import React, { useState, useEffect, useCallback } from 'react'; +import * as api from '../api'; +import type { Task, Project } from '../types'; + +export function Briefing() { + const [projects, setProjects] = useState([]); + const [selectedProject, setSelectedProject] = useState(''); + const [tasks, setTasks] = useState([]); + const [briefing, setBriefing] = useState(''); + + const loadProjects = useCallback(async () => { + try { + const data = await api.listProjects(); + setProjects(data); + if (data.length > 0 && !selectedProject) { + setSelectedProject(data[0].id); + } + } catch { /* ignore */ } + }, [selectedProject]); + + useEffect(() => { loadProjects(); }, [loadProjects]); + + const generateBriefing = useCallback(async () => { + if (!selectedProject) return; + try { + const data = await api.listTasks(selectedProject); + setTasks(data); + + // 本地生成简要汇报 + const done = data.filter(t => t.status === 'done'); + const working = data.filter(t => t.status === 'working'); + const failed = data.filter(t => t.status === 'failed'); + const pending = data.filter(t => t.status === 'pending'); + + const lines = [ + `📊 项目日报`, + ``, + `总任务数: ${data.length}`, + `✅ 已完成: ${done.length}`, + `🔄 进行中: ${working.length}`, + `⏳ 待处理: ${pending.length}`, + `❌ 失败: ${failed.length}`, + ``, + ]; + + if (working.length > 0) { + lines.push(`## 进行中的任务`); + working.forEach(t => lines.push(`- [${t.id.substring(0, 8)}] ${t.title} (${t.assignee || '未分配'})`)); + lines.push(''); + } + + if (failed.length > 0) { + lines.push(`## 失败的任务`); + failed.forEach(t => lines.push(`- [${t.id.substring(0, 8)}] ${t.title}`)); + lines.push(''); + } + + if (done.length > 0) { + lines.push(`## 最近完成`); + done.slice(-5).forEach(t => lines.push(`- [${t.id.substring(0, 8)}] ${t.title}`)); + } + + setBriefing(lines.join('\n')); + } catch { /* ignore */ } + }, [selectedProject]); + + return ( +
+

AI Briefing

+ +
+ + +
+ + {briefing && ( +
+
+            {briefing}
+          
+
+ )} + + {!briefing && ( +
+

选择项目并点击"生成汇报"查看项目状态概览。

+
+ )} +
+ ); +}