diff --git a/frontend-web/.env.development b/frontend-web/.env.development index 0d15230d..41decf09 100644 --- a/frontend-web/.env.development +++ b/frontend-web/.env.development @@ -7,6 +7,20 @@ VITE_LANGGRAPH_BASE_URL=http://127.0.0.1:8001/api # 轻应用「新建笔记」系列接口 VITE_NOTE_API_BASE_URL=http://47.88.25.99:8000 - +# CMZS后端接口 +VITE_API_BASE_URL=https://ch1.b.uat.4.cn/zncm +# 佳来模型对话接口 +VITE_AIPI_CHAT_URL=https://ch1.b.uat.4.cn/gpt +# 多轮检索接口 +VITE_AIPI_GENERATE_CHAT_URL=https://ch1.b.uat.4.cn/jialai_b1_chat +VITE_AIPI_TASK_CHAT_URL=https://ch1.b.uat.4.cn/qq_b1_chat +VITE_AIPI_KNOWLEDGE_URL=https://chlib.b.uat.4.cn/knowlibrary +VITE_AIPI_B1COH_URL=https://ch1.b.uat.4.cn/web +VITE_AIPI_B2ACTOR_URL=htttps://ty.b.uat.4.cn +VITE_AIPI_MOPECHAT_URL=https://ch1.b.uat.4.cn/likun_b1_mope +VITE_AIPI_BACKENP_URL=https://knowledgetoolserver.b.uat.4.cn +VITE_AIPI_CONSUMER_URL=https://ch1.b.uat.4.cn/consumer +VITE_AIPI_PGLINKTO_URL=https://pg.b.uat.4.cn +VITE_AIPI_XKLINKTO_URL=https://kz.b.uat.4.cn # 可选:Canvas 独立 LangGraph 地址(不设则回退到 VITE_LANGGRAPH_BASE_URL) # VITE_CANVAS_LANGGRAPH_BASE_URL= diff --git a/frontend-web/.env.development.local.example b/frontend-web/.env.development.local.example index 3f551f71..471b2649 100644 --- a/frontend-web/.env.development.local.example +++ b/frontend-web/.env.development.local.example @@ -3,5 +3,18 @@ VITE_BACKEND_BASE_URL=http://127.0.0.1:8001 VITE_LANGGRAPH_BASE_URL=http://127.0.0.1:8001/api +# 佳来模型对话接口 +VITE_AIPI_CHAT_URL=https://ch1.b.uat.4.cn/gpt +# 多轮检索接口 +VITE_AIPI_GENERATE_CHAT_URL=https://ch1.b.uat.4.cn/jialai_b1_chat +VITE_AIPI_TASK_CHAT_URL=https://ch1.b.uat.4.cn/qq_b1_chat +VITE_AIPI_KNOWLEDGE_URL=https://chlib.b.uat.4.cn/knowlibrary +VITE_AIPI_B1COH_URL=https://ch1.b.uat.4.cn/web +VITE_AIPI_B2ACTOR_URL=htttps://ty.b.uat.4.cn +VITE_AIPI_MOPECHAT_URL=https://ch1.b.uat.4.cn/likun_b1_mope +VITE_AIPI_BACKENP_URL=https://knowledgetoolserver.b.uat.4.cn +VITE_AIPI_CONSUMER_URL=https://ch1.b.uat.4.cn/consumer +VITE_AIPI_PGLINKTO_URL=https://pg.b.uat.4.cn +VITE_AIPI_XKLINKTO_URL=https://kz.b.uat.4.cn # VITE_NOTE_API_BASE_URL=http://127.0.0.1:8000 diff --git a/frontend-web/.env.production b/frontend-web/.env.production index 1d13e37e..0e94e082 100644 --- a/frontend-web/.env.production +++ b/frontend-web/.env.production @@ -7,6 +7,19 @@ VITE_LANGGRAPH_BASE_URL=https://ch1.b.uat.4.cn/deerflow/api # 轻应用「新建笔记」系列接口 VITE_NOTE_API_BASE_URL=https://your-intranet-host/note-api +# 佳来模型对话接口 +VITE_AIPI_CHAT_URL=https://ch1.b.uat.4.cn/gpt +# 多轮检索接口 +VITE_AIPI_GENERATE_CHAT_URL=https://ch1.b.uat.4.cn/jialai_b1_chat +VITE_AIPI_TASK_CHAT_URL=https://ch1.b.uat.4.cn/qq_b1_chat +VITE_AIPI_KNOWLEDGE_URL=https://chlib.b.uat.4.cn/knowlibrary +VITE_AIPI_B1COH_URL=https://ch1.b.uat.4.cn/web +VITE_AIPI_B2ACTOR_URL=htttps://ty.b.uat.4.cn +VITE_AIPI_MOPECHAT_URL=https://ch1.b.uat.4.cn/likun_b1_mope +VITE_AIPI_BACKENP_URL=https://knowledgetoolserver.b.uat.4.cn +VITE_AIPI_CONSUMER_URL=https://ch1.b.uat.4.cn/consumer +VITE_AIPI_PGLINKTO_URL=https://pg.b.uat.4.cn +VITE_AIPI_XKLINKTO_URL=https://kz.b.uat.4.cn # 可选:Canvas 独立 LangGraph 地址 # VITE_CANVAS_LANGGRAPH_BASE_URL= diff --git a/frontend-web/src/components/page-sdebar.css b/frontend-web/src/components/page-sdebar.css new file mode 100644 index 00000000..61890fb3 --- /dev/null +++ b/frontend-web/src/components/page-sdebar.css @@ -0,0 +1,24 @@ +.sidebar-contents{ + width:98px; + height:986px; + background:rgba(3, 38, 80, 0.8); + border:1px solid; + border-color:rgba(43, 143, 254, 0.6); + border-radius:4px; + backdrop-filter:blur(2px); +} + +.item-nav{ + width:78px; + height:70px; + background:rgba(0, 12, 28, 0.15); + border:1px solid; + border-color:rgba(85, 166, 254, 0.2); + line-height:8px; + font-family:Noto Sans S Chinese; + font-weight:500; + color:rgba(255, 255, 255, 0.8); + font-size:20px; + padding-bottom:18px; + text-align:center; +} \ No newline at end of file diff --git a/frontend-web/src/components/page-sidebar-dark.tsx b/frontend-web/src/components/page-sidebar-dark.tsx new file mode 100644 index 00000000..251e1d82 --- /dev/null +++ b/frontend-web/src/components/page-sidebar-dark.tsx @@ -0,0 +1,311 @@ +import { useEffect, useState } from "react"; +import type { ElementType } from "react"; +import { useNavigate, useLocation } from "react-router-dom"; +import { + Bell, + Bot, + Brain, + CalendarClock, + ChevronLeft, + ChevronRight, + ChevronsUpDown, + CircleHelp, + Database, + FileBox, + FileText, + Folder, + FolderOpen, + Gauge, + Grid3X3, + HelpCircle, + History, + Layout, + Library, + List, + ListChecks, + ListTodo, + MessageSquareCode, + MessageSquarePlus, + Network, + NotebookPen, + Plus, + Settings, + Sparkles, + Target, + User, + Users, + Wrench, +} from "lucide-react"; + +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu"; +import { NotificationDialog } from "@/components/workspace/notification-dialog"; +import { SettingsDialog } from "@/components/workspace/settings"; +import { useTheme } from "@/contexts/ThemeContext"; +import { getStoredAuth } from "@/core/auth"; +import { useI18n } from "@/core/i18n/hooks"; +import { useUnreadCount } from "@/core/notifications"; +import './page-sdebar.css' + +type MenuItem = { + id: string; + label: string; + icon: ElementType; + path?: string; + adminOnly?: boolean; + children?: MenuItem[]; +}; + +type PageSidebarDarkProps = { + collapsed: boolean; + onToggleCollapsed: () => void; +}; + +type SettingsSection = "account" | "appearance" | "memory" | "tools" | "about"; + +const menuItems: MenuItem[] = [ + { + id: "qa-center", + label: "问答中心", + icon: HelpCircle, + children: [ + { id: "general-qa", label: "通用问答", icon: CircleHelp, path: "/page/workspace/chats/new" }, + { id: "qa-zzjc", label: "zzjc支持", icon: Bot }, + { id: "qa-zzxd", label: "zzXD应用", icon: Layout }, + { id: "qa-research", label: "课题研究", icon: FileText, path: "/page/canvas/ai-writing" }, + ], + }, + { + id: "light-app-center", + label: "轻应用", + icon: Grid3X3, + children: [ + { + id: "light-app-note-management", + label: "笔记管理", + icon: NotebookPen, + children: [ + { + id: "light-app-new-note", + label: "新建笔记", + icon: Plus, + path: "/page/strategy/light-app/new-note", + }, + { + id: "light-app-note-list", + label: "笔记列表", + icon: List, + path: "/page/strategy/light-app/notes", + }, + { + id: "light-app-note-qa", + label: "笔记问答", + icon: MessageSquareCode, + path: "/page/strategy/light-app/note-qa", + }, + ], + }, + { id: "light-app-square", label: "应用广场", icon: Layout }, + { id: "light-app-records", label: "运行记录", icon: History }, + ], + }, + { + id: "task-management", + label: "任务管理", + icon: Target, + children: [ + { + id: "xk-center-task", + label: "XK中任务", + icon: Folder, + children: [ + { id: "xk-task-jc", label: "任务JC", icon: ListTodo, path: "/page/strategy/task-management/xk-task-jc" }, + { id: "xk-task-dispatch", label: "任务调度", icon: ListTodo, path: "/page/strategy/task-management/xk-task-dispatch" }, + ], + }, + { + id: "coh-center-task", + label: "COH中任务", + icon: Folder, + children: [ + { id: "coh-task-3qfx", label: "3QFX", icon: ListTodo }, + { id: "coh-task-fx", label: "任务FX", icon: ListTodo }, + { id: "coh-task-xdfx", label: "XDFX", icon: ListTodo }, + ], + }, + { + id: "pg-center-task", + label: "PG中任务", + icon: Folder, + children: [ + { id: "pg-task-pg", label: "任务PG", icon: ListTodo }, + { id: "pg-task-xdpg", label: "XDPG", icon: ListTodo }, + { id: "pg-task-info-pg", label: "信息PG", icon: ListTodo }, + ], + }, + { + id: "ty-center-task", + label: "TY中任务", + icon: Folder, + children: [ + { id: "ty-task-xdty", label: "XDTY任务", icon: ListTodo }, + { id: "ty-task-plan", label: "方案TY任务", icon: ListTodo }, + { id: "ty-task-xxty", label: "XXTY任务", icon: ListTodo }, + ], + }, + ], + }, + { + id: "comprehensive-management", + label: "综合管理", + icon: Settings, + children: [ + { id: "mgmt-agents", label: "智能体管理", icon: Bot, path: "/page/strategy/agents" }, + { id: "mgmt-skills", label: "技能管理", icon: Sparkles, path: "/page/strategy/skills" }, + { id: "mgmt-memory", label: "记忆管理", icon: Brain, path: "/page/strategy/memory" }, + { + id: "mgmt-tasks", + label: "任务管理", + icon: ListChecks, + path: "/page/strategy/scheduled/tasks", + }, + { + id: "mgmt-recommended-questions", + label: "推荐问题配置", + icon: MessageSquarePlus, + path: "/page/strategy/settings/recommended-questions", + adminOnly: true, + }, + { + id: "mgmt-prompt-prefix", + label: "问答前缀配置", + icon: MessageSquareCode, + path: "/page/strategy/settings/prompt-prefix", + adminOnly: true, + }, + { + id: "mgmt-llm-metrics", + label: "大模型调用统计", + icon: Gauge, + path: "/page/strategy/settings/llm-metrics", + adminOnly: true, + }, + { + id: "mgmt-users", + label: "用户管理", + icon: Users, + path: "/page/strategy/admin/users", + adminOnly: true, + }, + { + id: "mgmt-admin-scheduled-tasks", + label: "定时任务管理", + icon: CalendarClock, + path: "/page/strategy/admin/scheduled-tasks", + adminOnly: true, + }, + { + id: "mgmt-user-activity", + label: "用户活动审计", + icon: History, + path: "/page/strategy/admin/user-activity", + adminOnly: true, + }, + ], + }, + { + id: "resource-management", + label: "资源管理", + icon: Database, + children: [ + { id: "resource-network-xwt", label: "网络xwt资源管理", icon: Network }, + { id: "resource-knowledge-base", label: "知识库资源管理", icon: Library }, + { id: "resource-zz", label: "ZZ资源管理", icon: FileBox }, + ], + }, +]; + +const defaultExpandedIds = new Set([ + "qa-center", + "light-app-center", + "light-app-note-management", + "task-management", + "xk-center-task", +]); + +function filterMenuItemsByRole(items: MenuItem[], isAdmin: boolean): MenuItem[] { + return items + .filter((item) => !item.adminOnly || isAdmin) + .map((item) => + item.children + ? { ...item, children: filterMenuItemsByRole(item.children, isAdmin) } + : item, + ); +} + +export function PageSidebarDark({ + collapsed, + onToggleCollapsed, +}: PageSidebarDarkProps) { + const { theme } = useTheme(); + const isDark = theme === "dark"; + const isAdmin = getStoredAuth()?.system_role === "admin"; + const visibleMenuItems = filterMenuItemsByRole(menuItems, !!isAdmin); + const { t } = useI18n(); + const { data: unreadCount = 0 } = useUnreadCount(); + const [expandedIds, setExpandedIds] = useState>(defaultExpandedIds); + const [settingsOpen, setSettingsOpen] = useState(false); + const [settingsDefaultSection, setSettingsDefaultSection] = + useState("appearance"); + const [notificationOpen, setNotificationOpen] = useState(false); + const [mounted, setMounted] = useState(false); + const navigate = useNavigate(); + const { pathname } = useLocation(); + + useEffect(() => { + setMounted(true); + }, []); + + const openSettings = (section: SettingsSection) => { + setSettingsDefaultSection(section); + setSettingsOpen(true); + }; + + const toggleExpanded = (id: string) => { + setExpandedIds((prev) => { + const next = new Set(prev); + if (next.has(id)) { + next.delete(id); + } else { + next.add(id); + } + return next; + }); + }; + + return ( + <> + + + {/* TODO: 在这里编写深色主题的侧边栏 HTML 结构 */} +
+
+
+ 问答管理 +
+
+
+ + ); +} diff --git a/frontend-web/src/components/workspace/agents/agent-card.tsx b/frontend-web/src/components/workspace/agents/agent-card.tsx index f00ccdc2..9d4d7d1a 100644 --- a/frontend-web/src/components/workspace/agents/agent-card.tsx +++ b/frontend-web/src/components/workspace/agents/agent-card.tsx @@ -42,6 +42,7 @@ import { SkillDetailDialog } from "@/components/workspace/skills/skill-detail-di import { TagChipList } from "@/components/workspace/tags/tag-chip"; import { TagPickerDialog } from "@/components/workspace/tags/tag-picker-dialog"; import { + useAgent, useDeleteAgent, useSetAgentFeatured, useSetAgentPrivate, @@ -81,6 +82,13 @@ export function AgentCard({ agent }: AgentCardProps) { ); const [detailSkillName, setDetailSkillName] = useState(null); + // The /api/agents list response intentionally omits `soul` (perf optimization + // — SOUL.md is only read on demand). Fetch the detail row when the edit + // dialog opens so the SOUL textarea can be hydrated. + const { agent: agentDetail, isLoading: isAgentDetailLoading } = useAgent( + editOpen ? agent.id : null, + ); + const storedAuth = useMemo(() => getStoredAuth(), []); const currentUserId = storedAuth?.user_id ?? null; const isAdmin = storedAuth?.system_role === "admin"; @@ -105,7 +113,6 @@ export function AgentCard({ agent }: AgentCardProps) { } setEditName(agent.name); setEditDescription(agent.description ?? ""); - setEditSoul(agent.soul ?? ""); setEditPublished(agent.published); setEditIsPrivate(agent.is_private); setSelectedSkills(agent.skills ?? []); @@ -115,10 +122,23 @@ export function AgentCard({ agent }: AgentCardProps) { agent.name, agent.published, agent.skills, - agent.soul, editOpen, ]); + useEffect(() => { + if (!editOpen) { + return; + } + // SOUL.md only ships on the detail endpoint; fall back to whatever the list + // happened to carry so older deployments (or cached objects that still + // include `soul`) keep working. + if (agentDetail) { + setEditSoul(agentDetail.soul ?? ""); + } else { + setEditSoul(agent.soul ?? ""); + } + }, [agent.soul, agentDetail, editOpen]); + function handleChat() { router.push(`/page/workspace/agents/${agent.id}/chats/new`); } @@ -563,7 +583,11 @@ export function AgentCard({ agent }: AgentCardProps) {