From fc7576fea3ded116dc61f459b09c984c2b52429c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=91=A3=E5=AE=8F=E5=87=AF?= Date: Wed, 17 Jun 2026 17:31:24 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=9C=86=E6=A1=8C=E4=BC=9A=E5=95=86=20?= =?UTF-8?q?Step1=20=E5=B7=A6=E6=A0=8F=E6=A0=B7=E5=BC=8F=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=88=E4=B8=9A=E5=8A=A1=E9=93=BE=E5=85=B3=E7=B3=BB=E5=9B=BE?= =?UTF-8?q?/=E5=88=86=E6=9E=90=E8=AE=B0=E5=BD=95=E5=8D=A1=E7=89=87?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 业务链:红色主题卡片头+单选圆点+席位胶囊+描述;选中可展开关系图, 席位按 stages 分组用彩色圆形小图标排列,悬停浮层显示名称/描述 - 分析记录:圆角改 5px,新增已完成/未完成标签与「第 N 步」进度, 标题/状态/时间/步骤四角布局,加选中高亮与 hover 阴影 - 修复滚动容器 overflow 裁剪导致卡片左边框被切 Co-Authored-By: Claude Opus 4.8 (1M context) --- .../pages/RoundtablePlanningPage.tsx | 312 +++++++++++++++--- 1 file changed, 260 insertions(+), 52 deletions(-) diff --git a/frontend-web/src/roundtable-planning/pages/RoundtablePlanningPage.tsx b/frontend-web/src/roundtable-planning/pages/RoundtablePlanningPage.tsx index beabc8f1..a1cfe23a 100644 --- a/frontend-web/src/roundtable-planning/pages/RoundtablePlanningPage.tsx +++ b/frontend-web/src/roundtable-planning/pages/RoundtablePlanningPage.tsx @@ -1595,6 +1595,7 @@ export default function RoundtablePlanningPage() { selectedChainId={autoChainResult?.chain?.id ?? null} onSelectChain={handleSelectChainFromSidebar} onOpenDraft={drafts.handleLoadDraft} + activeDraftId={drafts.currentDraftId} /> {/* MIDDLE VIEWPORT */} @@ -2100,6 +2101,8 @@ interface LeftSidebarProps { onSelectChain: (chain: BusinessChain) => void; /** 需求 0616 #2:Step1 落地左栏「分析记录」点击 → 打开历史会商分析(加载草稿)。 */ onOpenDraft: (draftId: string) => void; + /** 当前已加载草稿 id(分析记录选中高亮用),来自 drafts.currentDraftId。 */ + activeDraftId: string | null; } function Step2SandboxSidebarSync({ @@ -2144,6 +2147,7 @@ function LeftSidebar({ selectedChainId, onSelectChain, onOpenDraft, + activeDraftId, }: LeftSidebarProps) { // 整片脱敏:左侧面板(任务概览/参与角色/人工参与等)的所有文本——标题、动态内容、 // 嵌套子组件文本一并脱敏。消息列表与沙箱是另外的容器,不挂此 Hook,保持原文。 @@ -2279,12 +2283,41 @@ function LeftSidebar({ selectedChainId={selectedChainId} onSelectChain={onSelectChain} onOpenDraft={onOpenDraft} + activeDraftId={activeDraftId} /> )} ); } +/** 「展开关系图」示例芯片的轮换配色(仅作视觉区分,无业务语义)。 */ +const SEAT_CHIP_PALETTE = [ + "bg-rose-50 text-rose-700 border-rose-200", + "bg-amber-50 text-amber-700 border-amber-200", + "bg-teal-50 text-teal-700 border-teal-200", + "bg-purple-50 text-purple-700 border-purple-200", + "bg-sky-50 text-sky-700 border-sky-200", + "bg-emerald-50 text-emerald-700 border-emerald-200", +]; + +/** + * 把业务链席位按 `stages`(分层并行编排)分组:组内并行、组间串行;无 `stages` + * (线性链)时每个席位单独成一层。仅供左栏「展开关系图」做编排示意展示。 + */ +function getChainStageGroups(chain: BusinessChain): BusinessChain["seats"][] { + const byId = new Map(chain.seats.map((s) => [s.agent_id, s])); + if (chain.stages && chain.stages.length > 0) { + return chain.stages + .map((stage) => + stage + .map((id) => byId.get(id)) + .filter((s): s is BusinessChain["seats"][number] => Boolean(s)), + ) + .filter((stage) => stage.length > 0); + } + return chain.seats.map((s) => [s]); +} + /** * 需求 0616 #2:多智能体会商 Step1(落地)左栏入口栏。 * - 业务链:仅公共链条(``listChains("public")``)前 3 个;点击以该链席位启动会商。 @@ -2295,12 +2328,15 @@ function RoundtableEntryRail({ selectedChainId, onSelectChain, onOpenDraft, + activeDraftId, }: { selectedChainId: string | null; onSelectChain: (chain: BusinessChain) => void; onOpenDraft: (draftId: string) => void; + activeDraftId: string | null; }) { const [chains, setChains] = useState([]); + const [expandedChainId, setExpandedChainId] = useState(null); const { drafts: records, refresh } = useRoundtableDrafts(); useEffect(() => { @@ -2333,51 +2369,170 @@ function RoundtableEntryRail({ return ( <> {/* 业务链(公共,前 3 个) */} -
-
- -

业务链

+
+
+ + + +

业务链

{chains.length === 0 ? (

暂无公共业务链

) : ( -
+
{chains.map((chain) => { const selected = selectedChainId === chain.id; + const graphOpen = expandedChainId === chain.id; + const stageGroups = getChainStageGroups(chain); + let seatColorIndex = 0; return ( -
-
- {chain.seats.length} 个席位 - {selected ? " · 已选" : ""} -
- + + + {/* 关系图示例:选中后可展开,把该链席位智能体用小图标排成编排示意 */} + {selected && ( +
+ + + {graphOpen && ( +
+ {stageGroups.length === 0 ? ( +

+ 该业务链暂无智能体席位 +

+ ) : ( +
+ {stageGroups.map((stage, si) => ( +
+ {si > 0 && ( + + )} + {stage.length > 1 && ( + + 并行 {stage.length} + + )} +
+ {stage.map((seat, sj) => { + const palette = + SEAT_CHIP_PALETTE[ + seatColorIndex++ % + SEAT_CHIP_PALETTE.length + ]; + return ( +
+ + + + {/* 悬停浮层显示名称 / 描述 */} +
+
+
+ {seat.name} +
+ {seat.description && ( +
+ {seat.description} +
+ )} +
+
+
+
+ ); + })} +
+
+ ))} +
+ )} +
+ )} +
+ )} +
); })}
@@ -2385,30 +2540,83 @@ function RoundtableEntryRail({
{/* 分析记录(圆桌历史草稿) */} -
-
- -

分析记录

+
+
+ + + +

分析记录

{records.length === 0 ? ( -

暂无分析记录

+

暂无分析记录

) : ( -
- {records.map((rec) => ( - - ))} -
+ <> +
+ {records.map((rec) => { + // 已完成:进行到第 3 步(执行过方案总结报告) + const completed = rec.furthestStep === 3; + // 选中:当前已加载的草稿(正在查看的那条) + const active = activeDraftId === rec.id; + return ( + + ); + })} +
+
+ 共 {records.length} 条分析记录 +
+ )}