From 29dbaeddf0f487c6565a6fab1f45942452a7f885 Mon Sep 17 00:00:00 2001 From: yanweidong Date: Tue, 21 Jul 2026 11:29:36 +0800 Subject: [PATCH] feat: redesign project AI agent page --- apps/web_v1/scripts/visual-check.mjs | 2 +- apps/web_v1/src/App.css | 168 ++++++++++++++++++ apps/web_v1/src/api/mappers.tsx | 2 +- apps/web_v1/src/pages/projects/project-ai.tsx | 113 +++++++----- .../pages/projects/project-new-channel.tsx | 2 +- apps/web_v1/src/pages/workspace-body.tsx | 4 +- 6 files changed, 238 insertions(+), 53 deletions(-) diff --git a/apps/web_v1/scripts/visual-check.mjs b/apps/web_v1/scripts/visual-check.mjs index dd5e8bd..341c0c3 100644 --- a/apps/web_v1/scripts/visual-check.mjs +++ b/apps/web_v1/scripts/visual-check.mjs @@ -131,7 +131,7 @@ const channelListHoverMetrics = await collectMetrics() const channelPageChecks = [] for (const channel of [ { label: '工作计划', pageClass: 'project-tasks-page', expectedHeading: '工作计划' }, - { label: 'AI 会话', pageClass: 'project-ai-page', expectedHeading: 'AI 会话' }, + { label: 'AI智能体', pageClass: 'project-ai-page', expectedHeading: 'AI智能体' }, { label: '笔记资料', pageClass: 'project-notes-page', expectedHeading: '笔记资料' }, { label: '计划任务', pageClass: 'project-cron-page', expectedHeading: '计划任务' }, { label: '新建频道', pageClass: 'project-new-channel-page', expectedHeading: '新建频道' }, diff --git a/apps/web_v1/src/App.css b/apps/web_v1/src/App.css index 863252b..80afd6e 100644 --- a/apps/web_v1/src/App.css +++ b/apps/web_v1/src/App.css @@ -1388,6 +1388,174 @@ text-overflow: ellipsis; } +.agent-chat-shell { + min-height: calc(100vh - 170px); + display: grid; + grid-template-columns: 280px minmax(0, 1fr); + gap: 0; + margin: -12px -16px -16px; + background: var(--senlin-panel); +} + +.agent-session-list.queue-section.arco-card, +.agent-chat-panel.queue-section.arco-card { + border-top: 0; + border-right: 0; + border-bottom: 0; + border-radius: 0; + box-shadow: none; +} + +.agent-session-list.queue-section.arco-card { + border-left: 0; + background: color-mix(in srgb, var(--senlin-bg) 72%, var(--senlin-panel)); +} + +.agent-session-list.queue-section .arco-card-body { + height: 100%; + display: flex; + flex-direction: column; + gap: 28px; + padding: 18px 20px; +} + +.agent-new-chat.arco-btn { + height: 48px; + justify-content: center; + border: 1px solid var(--senlin-border); + border-radius: 999px; + background: var(--senlin-panel); + color: var(--senlin-text); + font-size: 16px; + font-weight: 600; + box-shadow: 0 4px 14px rgba(29, 33, 41, 0.08); +} + +.agent-new-chat .arco-icon { + font-size: 18px; +} + +.agent-session-groups { + display: grid; + gap: 28px; + overflow: auto; + scrollbar-width: none; +} + +.agent-session-groups:hover { + scrollbar-width: thin; +} + +.agent-session-group { + display: grid; + gap: 12px; +} + +.agent-session-group > .arco-typography { + font-size: 14px; +} + +.agent-session { + width: 100%; + overflow: hidden; + border: 0; + border-radius: 6px; + background: transparent; + color: var(--senlin-text); + padding: 5px 0; + text-align: left; + text-overflow: ellipsis; + white-space: nowrap; + cursor: pointer; + font-size: 16px; + line-height: 1.55; +} + +.agent-session:hover, +.agent-session.active { + color: var(--senlin-primary); +} + +.agent-chat-panel.queue-section .arco-card-body { + position: relative; + min-height: calc(100vh - 170px); + display: grid; + grid-template-rows: minmax(0, 1fr) auto; + padding: 0; +} + +.agent-chat-main { + display: grid; + place-items: center; + padding: 80px 32px 190px; +} + +.agent-chat-main h2 { + margin: 0; + color: var(--senlin-text); + font-size: 28px; + font-weight: 800; +} + +.agent-composer { + width: min(860px, calc(100% - 80px)); + display: grid; + gap: 12px; + justify-self: center; + margin: 0 0 28px; + border: 1px solid var(--senlin-border); + border-radius: 24px; + background: var(--senlin-panel); + padding: 18px 16px 14px; + box-shadow: 0 16px 40px rgba(29, 33, 41, 0.08); +} + +.agent-composer .arco-textarea-wrapper { + border: 0; + background: transparent; + padding: 0 8px; +} + +.agent-composer textarea { + color: var(--senlin-text); + font-size: 18px; +} + +.agent-composer textarea::placeholder { + color: #a9b0bc; +} + +.agent-composer-footer { + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; +} + +.agent-model-chip.arco-btn { + height: 36px; + border-color: color-mix(in srgb, var(--senlin-primary) 32%, var(--senlin-border)); + border-radius: 999px; + background: var(--senlin-soft-blue); + color: var(--senlin-primary); + font-weight: 700; +} + +.agent-send-button.arco-btn { + width: 38px; + height: 38px; + background: #aebeff; +} + +.theme-dark .agent-session-list.queue-section.arco-card { + background: #1f1f1f; +} + +.theme-dark .agent-composer, +.theme-dark .agent-new-chat.arco-btn { + box-shadow: 0 16px 40px rgb(0 0 0 / 22%); +} + .reply-box, .chat-input { display: grid; diff --git a/apps/web_v1/src/api/mappers.tsx b/apps/web_v1/src/api/mappers.tsx index 564bea8..b6ee34e 100644 --- a/apps/web_v1/src/api/mappers.tsx +++ b/apps/web_v1/src/api/mappers.tsx @@ -95,7 +95,7 @@ function channelLabel(channel: BackendChannel) { case 'tasks': return '工作计划' case 'ai_sessions': - return 'AI 会话' + return 'AI智能体' case 'notes_sources': return '笔记资料' case 'cron': diff --git a/apps/web_v1/src/pages/projects/project-ai.tsx b/apps/web_v1/src/pages/projects/project-ai.tsx index e14678b..23b3f5e 100644 --- a/apps/web_v1/src/pages/projects/project-ai.tsx +++ b/apps/web_v1/src/pages/projects/project-ai.tsx @@ -1,70 +1,87 @@ -import { Avatar, Button, Card, Input, Space, Tag, Typography } from '@arco-design/web-react' -import { IconPlus, IconRobot, IconSend } from '@arco-design/web-react/icon' -import type { ProjectWorkspace } from './project-types' +import { Button, Card, Input, Space, Typography } from '@arco-design/web-react' +import { + IconArrowUp, + IconAttachment, + IconPlusCircle, + IconRobot, +} from '@arco-design/web-react/icon' +import type { AISession, ProjectWorkspace } from './project-types' -const { Title, Text, Paragraph } = Typography - -const messages = [ - { role: 'user', text: '请基于当前项目资料,整理本周风险和推进建议。' }, - { role: 'assistant', text: '我建议优先处理导出问题、权限边界和 Q3 策略评审,并把客户反馈同步到工作计划。' }, - { role: 'user', text: '把建议拆成可执行任务。' }, -] +const { Title, Text } = Typography export function ProjectAi({ activeWorkspace, onSelectItem }: { activeWorkspace: ProjectWorkspace; onSelectItem: (title: string) => void }) { const { aiSessions, project } = activeWorkspace - const selected = aiSessions[0] + const groupedSessions = groupSessions(aiSessions) return (
- AI 会话 - {project.name} 的项目内 AI session,左侧会话列表,右侧对话详情。 + AI智能体 + {project.name} 的项目内智能体工作台,选择专家后开始上下文对话。
-
-
- -
- Session - {aiSessions.length} +
+ + + +
+ {groupedSessions.length ? ( + groupedSessions.map((group) => ( +
+ {group.label} + {group.items.map((session, index) => ( + + ))} +
+ )) + ) : ( + 暂无对话 + )}
- {aiSessions.map((session, index) => ( - - ))}
- -
- {selected?.title ?? '暂无会话'} - 队列空闲 + +
+ 选择专家,开始对话
-
- {messages.map((message, index) => ( -
- {message.role === 'assistant' ? : '张'} - {message.text} -
- ))} -
-
- - - - - +
+ +
+ + +
) } + +function groupSessions(sessions: AISession[]) { + const labels = ['今天', '昨天', '7 天内'] + return labels.map((label) => ({ + label, + items: sessions.filter((session, index) => session.time.includes(label) || (!labels.some((item) => session.time.includes(item)) && labels.indexOf(label) === fallbackGroupIndex(index))), + })).filter((group) => group.items.length > 0) +} + +function fallbackGroupIndex(index: number) { + if (index === 0) return 0 + if (index === 1) return 1 + return 2 +} diff --git a/apps/web_v1/src/pages/projects/project-new-channel.tsx b/apps/web_v1/src/pages/projects/project-new-channel.tsx index 51f8032..8d97662 100644 --- a/apps/web_v1/src/pages/projects/project-new-channel.tsx +++ b/apps/web_v1/src/pages/projects/project-new-channel.tsx @@ -54,7 +54,7 @@ export function ProjectNewChannel({ activeWorkspace }: { activeWorkspace: Projec 外部资料库 项目流程页 RSS/探索结果 - AI 会话上下文 + AI智能体上下文
diff --git a/apps/web_v1/src/pages/workspace-body.tsx b/apps/web_v1/src/pages/workspace-body.tsx index 0338895..7ab2b36 100644 --- a/apps/web_v1/src/pages/workspace-body.tsx +++ b/apps/web_v1/src/pages/workspace-body.tsx @@ -80,7 +80,7 @@ export function WorkspacePage({ const workspaceMetrics = [ { title: '项目总数', value: projects.length, delta: `${urgentProjects} 个高优先级`, icon: , color: 'arcoblue' }, { title: '未完成计划', value: unfinishedTasks.length, delta: '跨项目聚合', icon: , color: 'green' }, - { title: 'AI 会话', value: aiSessions.length, delta: '项目内上下文', icon: , color: 'purple' }, + { title: 'AI智能体', value: aiSessions.length, delta: '项目内上下文', icon: , color: 'purple' }, { title: '知识资料', value: notes.length, delta: '笔记与资料合计', icon: , color: 'cyan' }, ] @@ -89,7 +89,7 @@ export function WorkspacePage({
工作台 - 所有项目的统一工作台,汇总项目任务、AI 会话和知识资产。 + 所有项目的统一工作台,汇总项目任务、AI智能体和知识资产。