diff --git a/CLAUDE.md b/CLAUDE.md index 24bf01d3..54243962 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -84,7 +84,7 @@ The frontend (`frontend-web/`) is a React 19 + Vite SPA: - **LLM streaming**: `@langchain/langgraph-sdk` streams messages from the backend via SSE - **UI**: Radix UI primitives + TailwindCSS v4 + shadcn-style components in `src/components/ui/` - **Shims**: `src/shims/` provides `next/link` and `next/navigation` polyfills (original code was Next.js) -- **Login URL params** (`LoginPage.tsx`, frontend-only — the backend never sees these): besides the auth params (`ticket`/`userId`/`env`/`theme`/`yUserId`/`token`/`access_token`/`authToken`/`password`), the page supports a **task deep-link** via `?taskId=&goPath=`. After login it calls the consumer API `GET {VITE_AIPI_CONSUMER_URL}/taskAnalysSearch/cop-task-detail?taskId=` (header `Authorization: Bearer admin`, auto-injected by `utils/request.ts`), stashes the full `data` (`id/overview/taskDirection/taskName/taskContent`) into `sessionStorage["login.copTaskDetail"]`, then routes by `goPath`: base codes `3qfx`/`rwfx`/`xdfx` → that business's configured **single agent** Q&A (resolved via `/api/business-mapping`, opening message in `sessionStorage.pendingAgentMessage`); the `-A` suffix (`3qfx-A`/…) → **multi-agent roundtable** with `roundtablePrefill.businessCode` so the page auto-selects the configured 业务链条. goPath→businessCode: `3qfx`→`3Q`, `rwfx`→`6BF`, `xdfx`→`7BF`. **Both targets render embedded under the 任务管理 layout** — nested routes under `task-management//{roundtable,agent/:agent_id/chats/:thread_id}` in `StrategyRoutes.tsx` (`` = `plan-task-sentiment` / `plan-task/plan-task-fx` / `plan-task/plan-task-action`, matching the COH中任务 menu paths in `sidebar-menu.ts`) so the global sidebar keeps 任务管理 → COH中任务 → the matching business highlighted. The agent chat is rendered via `TaskEmbeddedAgentChat`, which passes `AgentChatPage`'s `chatBasePath` prop so the post-send URL rewrite + new-chat button stay in the task-management context (instead of the standalone `/agents/...` route). Any failure (no consumer URL / fetch error / unmapped goPath / no configured agent) silently falls back to the default home. Helpers: `core/auth/task-deeplink.ts`. +- **Login URL params** (`LoginPage.tsx`, frontend-only — the backend never sees these): besides the auth params (`ticket`/`userId`/`env`/`theme`/`yUserId`/`token`/`access_token`/`authToken`/`password`), the page supports a **task deep-link** via `?taskId=&goPath=`. After login it calls the consumer API `GET {VITE_AIPI_CONSUMER_URL}/taskAnalyseSearch/cop-task-detail?taskId=` (header `Authorization: Bearer admin`, auto-injected by `utils/request.ts`), stashes the full `data` (`id/overview/taskDirection/taskName/taskContent`) into `sessionStorage["login.copTaskDetail"]`, then routes by `goPath`: base codes `3qfx`/`rwfx`/`xdfx` → that business's configured **single agent** Q&A (resolved via `/api/business-mapping`, opening message in `sessionStorage.pendingAgentMessage`); the `-A` suffix (`3qfx-A`/…) → **multi-agent roundtable** with `roundtablePrefill.businessCode` so the page auto-selects the configured 业务链条. goPath→businessCode: `3qfx`→`3Q`, `rwfx`→`6BF`, `xdfx`→`7BF`. **Both targets render embedded under the 任务管理 layout** — nested routes under `task-management//{roundtable,agent/:agent_id/chats/:thread_id}` in `StrategyRoutes.tsx` (`` = `plan-task-sentiment` / `plan-task/plan-task-fx` / `plan-task/plan-task-action`, matching the COH中任务 menu paths in `sidebar-menu.ts`) so the global sidebar keeps 任务管理 → COH中任务 → the matching business highlighted. The agent chat is rendered via `TaskEmbeddedAgentChat`, which passes `AgentChatPage`'s `chatBasePath` prop so the post-send URL rewrite + new-chat button stay in the task-management context (instead of the standalone `/agents/...` route). Any failure (no consumer URL / fetch error / unmapped goPath / no configured agent) silently falls back to the default home. Helpers: `core/auth/task-deeplink.ts`. ### Configuration diff --git a/frontend-web/.env.development b/frontend-web/.env.development index 5ea0eb44..22563825 100644 --- a/frontend-web/.env.development +++ b/frontend-web/.env.development @@ -4,6 +4,9 @@ # 任务看板数据源:true=真实接口(默认);改成 false 可让任务分析/三情分析两页走本地假数据。 VITE_USE_REAL_DATA=true +# 任务详情(登录深链 cop-task-detail)数据源:默认真实接口;改成 true 走本地假数据(consumer 外网不可达时调试用)。 +VITE_MOCK_COP_TASK_DETAIL=false + # Gateway / DeerFlow API VITE_BACKEND_BASE_URL=http://127.0.0.1:8001 VITE_LANGGRAPH_BASE_URL=http://127.0.0.1:8001/api diff --git a/frontend-web/.env.example b/frontend-web/.env.example index e254e6c8..1b3d80bb 100644 --- a/frontend-web/.env.example +++ b/frontend-web/.env.example @@ -33,6 +33,11 @@ # 仅本机 .env 默认 false(假数据)。改后需重启 dev / 重新打包生效。 # VITE_USE_REAL_DATA=true +# --- 任务详情(登录深链 cop-task-detail)数据源开关 --- +# 默认真实接口(未设/false);改成 true 时该接口走本地假数据(consumer 外网不可达时调试用)。 +# 与 VITE_USE_REAL_DATA 独立。改后需重启 dev / 重新打包生效。 +# VITE_MOCK_COP_TASK_DETAIL=false + # MaxKey 鉴权根地址(无界 onlineTicket 换 token) # VITE_AUTH_BASE_URL=https://auth.y.sit.4.cn # VITE_AIPI_CONSUMER_URL=https://ch1.b.uat.4.cn/consumer diff --git a/frontend-web/.env.network b/frontend-web/.env.network index 569b8422..471b6289 100644 --- a/frontend-web/.env.network +++ b/frontend-web/.env.network @@ -4,6 +4,9 @@ # 任务看板数据源:true=真实接口(默认);改成 false 可让任务分析/三情分析两页走本地假数据。 VITE_USE_REAL_DATA=true +# 任务详情(登录深链 cop-task-detail)数据源:默认真实接口;改成 true 走本地假数据(调试用)。 +VITE_MOCK_COP_TASK_DETAIL=false + # Gateway / DeerFlow API VITE_BACKEND_BASE_URL=http://47.88.25.99:7001 VITE_LANGGRAPH_BASE_URL=http://47.88.25.99:7001/api diff --git a/frontend-web/.env.production b/frontend-web/.env.production index 08bf2a70..97415742 100644 --- a/frontend-web/.env.production +++ b/frontend-web/.env.production @@ -4,6 +4,9 @@ # 任务看板数据源:true=真实接口(默认);改成 false 可让任务分析/三情分析两页走本地假数据。 VITE_USE_REAL_DATA=true +# 任务详情(登录深链 cop-task-detail)数据源:默认真实接口;改成 true 走本地假数据(调试用)。 +VITE_MOCK_COP_TASK_DETAIL=false + # Gateway / DeerFlow API VITE_BACKEND_BASE_URL=https://ch1.b.uat.4.cn/deerflow VITE_LANGGRAPH_BASE_URL=https://ch1.b.uat.4.cn/deerflow/api diff --git a/frontend-web/.env.sit b/frontend-web/.env.sit index d4a4af7b..91ba650f 100644 --- a/frontend-web/.env.sit +++ b/frontend-web/.env.sit @@ -4,6 +4,9 @@ # 任务看板数据源:true=真实接口(默认);改成 false 可让任务分析/三情分析两页走本地假数据。 VITE_USE_REAL_DATA=true +# 任务详情(登录深链 cop-task-detail)数据源:默认真实接口;改成 true 走本地假数据(调试用)。 +VITE_MOCK_COP_TASK_DETAIL=false + # Gateway / DeerFlow API VITE_BACKEND_BASE_URL=https://ch1.b.sit.4.cn/deerflow VITE_LANGGRAPH_BASE_URL=https://ch1.b.sit.4.cn/deerflow/api diff --git a/frontend-web/src/components/workspace/general-qa-sidebar.tsx b/frontend-web/src/components/workspace/general-qa-sidebar.tsx index 8eb784ca..af4b7e4f 100644 --- a/frontend-web/src/components/workspace/general-qa-sidebar.tsx +++ b/frontend-web/src/components/workspace/general-qa-sidebar.tsx @@ -38,6 +38,7 @@ import { useCallback, useMemo, useState } from "react"; import { useNavigate } from "react-router-dom"; import { toast } from "sonner"; +import { useTheme } from "@/contexts/ThemeContext"; import { Button } from "@/components/ui/button"; import { Dialog, @@ -96,7 +97,9 @@ const MORE_CHATS_HREF = "/page/workspace/chats"; const MAX_FREQUENT = 4; // 智能体图标统一用 Bot 机器人图标;底色按 id 稳定散列到一组主题色,复刻参考图的彩色方块。 -const AGENT_COLORS = [ +// 浅色模式沿用原高彩度彩色(不改);深蓝主题改用《深蓝 UI 规范》§1.1.7/§1.1.8 的蓝-青系 +// (docs/ui规范-深蓝,克制、不刺眼),仅深蓝主题下生效,互不影响。 +const AGENT_COLORS_LIGHT = [ { from: "#fb7185", to: "#ef4444" }, { from: "#60a5fa", to: "#3b82f6" }, { from: "#fbbf24", to: "#f59e0b" }, @@ -104,12 +107,21 @@ const AGENT_COLORS = [ { from: "#a78bfa", to: "#8b5cf6" }, ] as const; -function agentColor(id: string) { +const AGENT_COLORS_DARK = [ + { from: "#4096FF", to: "#1677FF" }, // 蓝(链接蓝 → 主色) + { from: "#36CFC9", to: "#13C2C2" }, // 青(辅色) + { from: "#6388FF", to: "#0958D9" }, // 紫蓝(装饰紫 → 主色深一档) + { from: "#5CDBD3", to: "#08979C" }, // 浅青 → 深青 + { from: "#69B1FF", to: "#003EB3" }, // 浅蓝 → 主色按下 +] as const; + +function agentColor(id: string, isDark: boolean) { let hash = 0; for (let i = 0; i < id.length; i++) { hash = (hash * 31 + id.charCodeAt(i)) >>> 0; } - return AGENT_COLORS[hash % AGENT_COLORS.length]!; + const palette = isDark ? AGENT_COLORS_DARK : AGENT_COLORS_LIGHT; + return palette[hash % palette.length]!; } /** 折叠区块标题(带 chevron 与可选计数徽标)。 */ @@ -150,6 +162,9 @@ function SectionLabel({ export function GeneralQaSidebar() { const { t } = useI18n(); + // 智能体图标配色分主题:深蓝主题用规范蓝-青系,其它(浅色)保持原高彩度色,互不影响。 + const { theme } = useTheme(); + const isDark = theme === "dark"; const pathname = usePathname(); const router = useRouter(); const navigate = useNavigate(); @@ -309,12 +324,14 @@ export function GeneralQaSidebar() { const isStatic = env.NEXT_PUBLIC_STATIC_WEBSITE_ONLY === "true"; return ( -
+ // 背景走 sidebar token(浅主题=白、深蓝主题=深蓝),不要写死 bg-white,否则全量版深蓝主题下侧栏仍是白底。 +
{/* ── 顶部:新对话胶囊 + 收起按钮 ── */}
{/* 新对话按钮:完全自定义样式(不复用 Button variant)。borderColor / color 走 - inline style,避免被全局 border-color(--border)覆盖;无阴影。浅主色底 + 主色描边 - + 5px 圆角,全部走 --primary token,自动适配红/蓝/深蓝主题。 */} + inline style,避免被全局 border-color(--border)覆盖;无阴影。主色描边 + 5px 圆角。 + 底色用「主色混入透明」=主色低透明度叠在当前侧栏底色上,浅/红/蓝/深蓝主题都自适应 + (不要混 white,否则深蓝主题下会变成浅色块)。 */} @@ -344,7 +361,7 @@ export function GeneralQaSidebar() {
{frequent.map((agent) => { const isActive = activeAgentId === agent.id; - const { from, to } = agentColor(agent.id); + const { from, to } = agentColor(agent.id, isDark); return ( +
+

+ {editing ? '编辑研究模板' : '新建研究模板'} +

+

+ 左侧用问答描述需求,自动填好右侧字段;也可手动编辑。 +

+
+
+
+ {formError && {formError}} + + +
+ + +
+ {/* 左:模板助手问答(同 AI 写作 setup 机制)→ 应用到右侧表单。问答区更宽(约 7:3)。 */} +
+ +
+ + {/* 右:模板表单 */} +
+
+ + set('name', e.target.value)} + placeholder="如:深度舆情分析" + /> +
+
+ + set('description', e.target.value)} + placeholder="模板用途简述" + /> +
+
+ + +
+
+ + +
+
+ + set('word_count', e.target.value)} + /> +
+
+ + set('audience', e.target.value)} + placeholder="如:决策者" + /> +
+
+ +