diff --git a/frontend-web/src/components/workspace/agents/agent-detail-panel.tsx b/frontend-web/src/components/workspace/agents/agent-detail-panel.tsx index f9a3292e..9a40afc3 100644 --- a/frontend-web/src/components/workspace/agents/agent-detail-panel.tsx +++ b/frontend-web/src/components/workspace/agents/agent-detail-panel.tsx @@ -131,14 +131,17 @@ export function AgentDetailPanel({ agentName, onAskQuestion, disabled, + defaultCollapsed, }: { agent: Agent | null | undefined; agentName: string; onAskQuestion: (text: string) => void; disabled?: boolean; + /** 初始收起(任务工作区进入时默认收起智能体信息面板)。 */ + defaultCollapsed?: boolean; }) { const router = useRouter(); - const [collapsed, setCollapsed] = useState(false); + const [collapsed, setCollapsed] = useState(defaultCollapsed ?? false); const [mobileOpen, setMobileOpen] = useState(false); const [editing, setEditing] = useState(false); const [draft, setDraft] = useState(null); diff --git a/frontend-web/src/pages/AgentChatPage.tsx b/frontend-web/src/pages/AgentChatPage.tsx index b169212e..12c09a2b 100644 --- a/frontend-web/src/pages/AgentChatPage.tsx +++ b/frontend-web/src/pages/AgentChatPage.tsx @@ -435,6 +435,7 @@ export default function AgentChatPage({ agentName={agentDisplayName} disabled={thread.isLoading || isDemoMode} onAskQuestion={(text) => handleSubmit({ text, files: [] })} + defaultCollapsed={taskCtxOn} /> diff --git a/frontend-web/src/strategy-components/components/task-components/TaskFxWorkspace.tsx b/frontend-web/src/strategy-components/components/task-components/TaskFxWorkspace.tsx index 637dad94..ace8bd25 100644 --- a/frontend-web/src/strategy-components/components/task-components/TaskFxWorkspace.tsx +++ b/frontend-web/src/strategy-components/components/task-components/TaskFxWorkspace.tsx @@ -36,6 +36,7 @@ import { type TaskDeeplinkConfig, } from "@/core/auth/task-deeplink-config"; import { + TASK_BUSINESSES, buttonsForBusiness, resolveTaskButtons, runTaskButton, @@ -120,6 +121,10 @@ function TaskJumpBar({ business, taskId }: { business: TaskBusiness; taskId: str // 目的树弹框(purpose 类型按钮)由组件层打开。 const [purposeOpen, setPurposeOpen] = useState(false); + // xdfx:深链原始「行动id」(与解析后的任务id 不同才算真行动id),弹框据此换回任务id 再查目的。 + const ctxActionId = readTaskContext()?.actionId; + const purposeActionId = + business === "xdfx" && ctxActionId && ctxActionId !== taskId ? ctxActionId : undefined; if (jumpButtons.length === 0) return null; @@ -141,7 +146,7 @@ function TaskJumpBar({ business, taskId }: { business: TaskBusiness; taskId: str {jumpButtons.map((btn) => ( ))} - + ); } @@ -168,21 +178,29 @@ function TaskConversationsList({ taskId, agentId, chatsBase, + business, lite, }: { taskId: string; agentId: string; chatsBase: string; + business: TaskBusiness; lite?: boolean; }) { const { pathname } = useLocation(); const navigate = useNavigate(); const { threads, isLoading } = useTaskThreads(taskId, agentId); const currentThreadId = useMemo(() => parseThreadId(pathname, chatsBase), [pathname, chatsBase]); + const businessName = TASK_BUSINESSES.find((b) => b.code === business)?.name ?? ""; return (
+ {/* 左上角标明当前是哪个分析页面 */} +
+ + {businessName} +
@@ -318,6 +336,7 @@ export function TaskFxWorkspace({ taskId={taskId} agentId={agentId} chatsBase={chatsBase} + business={business} lite={lite} />
diff --git a/frontend-web/src/strategy-components/components/task-components/TaskPurposePanel.tsx b/frontend-web/src/strategy-components/components/task-components/TaskPurposePanel.tsx index 178b13a5..56bc1f1c 100644 --- a/frontend-web/src/strategy-components/components/task-components/TaskPurposePanel.tsx +++ b/frontend-web/src/strategy-components/components/task-components/TaskPurposePanel.tsx @@ -30,6 +30,7 @@ import { type PurposeTreeNode, type TaskPurposeResult, } from "@/core/auth/task-purpose"; +import { fetchTaskIdFromAction } from "@/core/auth/task-deeplink"; import { cn } from "@/lib/utils"; /** 目的树表格:拍平成行,列数随数据自适应;层级缺失补空、字段变动不崩。 */ @@ -98,32 +99,49 @@ export function TaskPurposeDialog({ taskId, open, onOpenChange, + resolveFromActionId, }: { taskId: string; open: boolean; onOpenChange: (open: boolean) => void; + /** xdfx:深链原始「行动id」。提供时弹框先用它换出真正「任务id」再查目的树。 */ + resolveFromActionId?: string; }) { const [loading, setLoading] = useState(false); const [result, setResult] = useState(null); + const [resolvedTaskId, setResolvedTaskId] = useState(taskId); useEffect(() => { if (!open) return; let cancelled = false; setLoading(true); - fetchTaskPurposeDetail(taskId) - .then((r) => !cancelled && setResult(r)) - .catch(() => !cancelled && setResult({ tree: [], hasData: false })) - .finally(() => !cancelled && setLoading(false)); + (async () => { + try { + // xdfx:行动id 换任务id 再查目的树(与登录时的解析一致);无行动id 时直接用任务id。 + let tid = taskId; + if (resolveFromActionId) { + tid = (await fetchTaskIdFromAction(resolveFromActionId)) || taskId; + } + if (cancelled) return; + setResolvedTaskId(tid); + const r = await fetchTaskPurposeDetail(tid); + if (!cancelled) setResult(r); + } catch { + if (!cancelled) setResult({ tree: [], hasData: false }); + } finally { + if (!cancelled) setLoading(false); + } + })(); return () => { cancelled = true; }; - }, [open, taskId]); + }, [open, taskId, resolveFromActionId]); return ( - 任务目的(任务 {taskId}) + 任务目的(任务 {resolvedTaskId}) {loading ? (