diff --git a/src/api/membership.ts b/src/api/membership.ts index 6645100..6eed303 100644 --- a/src/api/membership.ts +++ b/src/api/membership.ts @@ -93,13 +93,13 @@ export const MembershipAPI = { /** * 授权资源(智能体/知识库)访问 */ - authorizeResource: (payload: { userId: string; resourceType: 'agent' | 'knowledge'; resourceId: string; level: 'read' | 'write' }) => + authorizeResource: (payload: { userId: string; resourceType: 'agent' | 'knowledge'; resourceIds: string[]; level: 'read' | 'write' }) => api.post>('/membership/access', payload).then(r => r.data), /** * 取消资源授权 */ - revokeResource: (payload: { userId: string; resourceType: 'agent' | 'knowledge'; resourceId: string }) => + revokeResource: (payload: { userId: string; resourceType: 'agent' | 'knowledge'; resourceIds: string[] }) => api.delete>('/membership/access', { data: payload }).then(r => r.data), /** diff --git a/src/api/teams.ts b/src/api/teams.ts index 4609ae8..2ab5439 100644 --- a/src/api/teams.ts +++ b/src/api/teams.ts @@ -15,6 +15,7 @@ export const TeamAPI = { detail: (id: string) => api.get(`/teams/${id}`).then((r) => r.data), create: (name: string) => api.post('/teams', { name }).then((r) => r.data), rename: (id: string, name: string) => api.put(`/teams/${id}`, { name }).then((r) => r.data), + addMember: (id: string, phone: string) => api.post(`/teams/${id}/members`, { phone }).then((r) => r.data), remove: (id: string) => api.delete(`/teams/${id}`).then((r) => r.data), removeMember: (id: string, userId: string) => api.delete(`/teams/${id}/members/${userId}`).then((r) => r.data) }; diff --git a/src/components/ExternalToolEditor/index.tsx b/src/components/ExternalToolEditor/index.tsx index a5fc252..bc122f8 100644 --- a/src/components/ExternalToolEditor/index.tsx +++ b/src/components/ExternalToolEditor/index.tsx @@ -193,6 +193,14 @@ export default function ExternalToolEditor({ open, agentId, plugin, onClose, onS onOk={handleSubmit} destroyOnHidden afterOpenChange={handleAfterOpenChange} + maskClosable={false} + styles={{ + body: { + maxHeight: '70vh', + overflowY: 'auto', + paddingRight: 12 + } + }} >
, label: '聊天' }, { to: '/agents', icon: , label: '我的智能体' }, - { to: '/marketplace', icon: , label: '智能体广场' } + // { to: '/marketplace', icon: , label: '智能体广场' } ] }, { diff --git a/src/pages/AgentList/components/AgentListH5.tsx b/src/pages/AgentList/components/AgentListH5.tsx index 2b511be..2aae684 100644 --- a/src/pages/AgentList/components/AgentListH5.tsx +++ b/src/pages/AgentList/components/AgentListH5.tsx @@ -38,10 +38,10 @@ export default function AgentListH5({ logic }: Props) { type="primary" size="middle" icon={} - onClick={() => navigate('/marketplace')} + onClick={() => navigate('/agents/new')} className="h5-stats-marketplace-btn" > - 前往智能体广场 + 创建智能体 @@ -69,8 +69,8 @@ export default function AgentListH5({ logic }: Props) { {!loading && list.length === 0 ? (
-
diff --git a/src/pages/AgentList/components/AgentListWeb.css b/src/pages/AgentList/components/AgentListWeb.css index 353fe0d..7f65aaa 100644 --- a/src/pages/AgentList/components/AgentListWeb.css +++ b/src/pages/AgentList/components/AgentListWeb.css @@ -126,14 +126,14 @@ .agent-card-desc-container { margin-top: 16px; - padding: 16px 16px 18px; + padding: 16px; border-radius: 16px; background: linear-gradient(180deg, rgba(248,250,252,0.9) 0%, rgba(255,255,255,0.95) 100%); border: 1px solid rgba(148, 163, 184, 0.14); } .agent-card-desc { - min-height: 66px; + min-height: 48px; font-size: 13.5px; line-height: 1.7; display: -webkit-box; diff --git a/src/pages/AgentList/components/AgentListWeb.tsx b/src/pages/AgentList/components/AgentListWeb.tsx index 48108d9..4fbbcb3 100644 --- a/src/pages/AgentList/components/AgentListWeb.tsx +++ b/src/pages/AgentList/components/AgentListWeb.tsx @@ -42,10 +42,10 @@ export default function AgentListWeb({ logic }: Props) { type="primary" size="large" icon={} - onClick={() => navigate('/marketplace')} + onClick={() => navigate('/agents/new')} style={{ borderRadius: 14, height: 46, padding: '0 18px', fontWeight: 600 }} > - 前往智能体广场 + 创建智能体 @@ -73,8 +73,8 @@ export default function AgentListWeb({ logic }: Props) { {!loading && list.length === 0 ? (
-
diff --git a/src/pages/AgentList/components/AgentListWebBase.tsx b/src/pages/AgentList/components/AgentListWebBase.tsx index 09a4ec9..ce76c9a 100644 --- a/src/pages/AgentList/components/AgentListWebBase.tsx +++ b/src/pages/AgentList/components/AgentListWebBase.tsx @@ -30,8 +30,8 @@ export default function AgentListWebBase({ logic, viewport }: AgentListWebVarian 把你的 AI 助手沉淀成一组可管理、可协作、可持续进化的能力单元。创建入口统一在智能体广场,这里负责查看、进入和运营它们。 - @@ -53,8 +53,8 @@ export default function AgentListWebBase({ logic, viewport }: AgentListWebVarian {!loading && list.length === 0 ? (
-
diff --git a/src/pages/Profile/ProfileLogic.ts b/src/pages/Profile/ProfileLogic.ts index 27caa43..3b64ac5 100644 --- a/src/pages/Profile/ProfileLogic.ts +++ b/src/pages/Profile/ProfileLogic.ts @@ -98,9 +98,9 @@ export function useProfileLogic() { } }; - const handleAuthorizeAgent = async (userId: string, agentId: string, level: 'read' | 'write') => { + const handleAuthorizeAgent = async (userId: string, agentIds: string[], level: 'read' | 'write') => { try { - await MembershipAPI.authorizeResource({ userId, resourceType: 'agent', resourceId: agentId, level }); + await MembershipAPI.authorizeResource({ userId, resourceType: 'agent', resourceIds: agentIds, level }); message.success('授权成功'); const mList = await MembershipAPI.listMembers(); setMembers(mList); @@ -109,9 +109,9 @@ export function useProfileLogic() { } }; - const handleRevokeAgent = async (userId: string, agentId: string) => { + const handleRevokeAgent = async (userId: string, agentIds: string[]) => { try { - await MembershipAPI.revokeResource({ userId, resourceType: 'agent', resourceId: agentId }); + await MembershipAPI.revokeResource({ userId, resourceType: 'agent', resourceIds: agentIds }); message.success('取消授权成功'); const mList = await MembershipAPI.listMembers(); setMembers(mList); diff --git a/src/pages/Profile/components/ProfileH5.tsx b/src/pages/Profile/components/ProfileH5.tsx index f5a5f71..35630b3 100644 --- a/src/pages/Profile/components/ProfileH5.tsx +++ b/src/pages/Profile/components/ProfileH5.tsx @@ -1,5 +1,5 @@ import { useState } from 'react'; -import { Button, Modal, Input, Select, Space, Tag, InputNumber, Popconfirm, List, Card } from 'antd'; +import { Button, Modal, Input, Select, Space, Tag, InputNumber, Popconfirm, List, Card, Checkbox, Divider } from 'antd'; import { UserAddOutlined, DeleteOutlined, KeyOutlined, DashboardOutlined } from '@ant-design/icons'; import type { ProfileLogicOutput } from '../ProfileLogic'; import '../styles/profile.css'; @@ -30,7 +30,7 @@ export default function ProfileH5({ logic }: Props) { const [newChildId, setNewChildId] = useState(''); const [selectedMember, setSelectedMember] = useState(null); const [quotaAmount, setQuotaAmount] = useState(100000); - const [selectedAgentId, setSelectedAgentId] = useState(''); + const [selectedAgentIds, setSelectedAgentIds] = useState([]); return (
@@ -90,7 +90,14 @@ export default function ProfileH5({ logic }: Props) { style={{ marginBottom: 12, borderRadius: 12 }} actions={[ { setSelectedMember(record); setQuotaModalVisible(true); }} />, - { setSelectedMember(record); setAuthModalVisible(true); }} />, + { + setSelectedMember(record); + setSelectedAgentIds(record.authorizedAgentIds || []); + setAuthModalVisible(true); + }} + />, handleRemoveChild(record.id)}> , @@ -112,13 +119,23 @@ export default function ProfileH5({ logic }: Props) { handleRevokeAgent(record.child_user_id, id)} - style={{ borderRadius: 4, fontSize: 10, margin: '2px' }} + onClose={() => handleRevokeAgent(record.child_user_id, [id])} + style={{ borderRadius: 4, fontSize: 10, margin: '2px', display: 'flex', width: 'fit-content' }} > - {agent?.name || '未知'} + 🤖 {agent?.name || '未知'} ); })} + {record.authorizedAgentIds?.length > 0 && ( + handleRevokeAgent(record.child_user_id, record.authorizedAgentIds)} + > + + + )}
} @@ -163,12 +180,42 @@ export default function ProfileH5({ logic }: Props) { { handleAuthorizeAgent(selectedMember.child_user_id, selectedAgentId, 'read'); setAuthModalVisible(false); setSelectedAgentId(''); }} - onCancel={() => setAuthModalVisible(false)} + onOk={() => { + handleAuthorizeAgent(selectedMember.child_user_id, selectedAgentIds, 'read'); + setAuthModalVisible(false); + setSelectedAgentIds([]); + }} + onCancel={() => { + setAuthModalVisible(false); + setSelectedAgentIds([]); + }} > - +
+ 选择智能体 + 0 && selectedAgentIds.length < myAgents.length} + checked={selectedAgentIds.length === myAgents.length && myAgents.length > 0} + onChange={(e) => { + setSelectedAgentIds(e.target.checked ? myAgents.map(a => a.id) : []); + }} + > + 全选 + +
+ +
+ setSelectedAgentIds(vals as string[])} + > +
+ {myAgents.map(a => ( + {a.name} + ))} +
+
+
); diff --git a/src/pages/Profile/components/ProfileWeb.tsx b/src/pages/Profile/components/ProfileWeb.tsx index 8d36c16..977217b 100644 --- a/src/pages/Profile/components/ProfileWeb.tsx +++ b/src/pages/Profile/components/ProfileWeb.tsx @@ -1,5 +1,5 @@ import { useState } from 'react'; -import { Button, Table, Modal, Input, Select, Space, Tag, InputNumber, Popconfirm } from 'antd'; +import { Button, Table, Modal, Input, Select, Space, Tag, InputNumber, Popconfirm, Checkbox, Divider } from 'antd'; import { UserAddOutlined, DeleteOutlined, KeyOutlined, DashboardOutlined } from '@ant-design/icons'; import type { ProfileLogicOutput } from '../ProfileLogic'; import '../styles/profile.css'; @@ -30,7 +30,7 @@ export default function ProfileWeb({ logic }: Props) { const [newChildId, setNewChildId] = useState(''); const [selectedMember, setSelectedMember] = useState(null); const [quotaAmount, setQuotaAmount] = useState(100000); - const [selectedAgentId, setSelectedAgentId] = useState(''); + const [selectedAgentIds, setSelectedAgentIds] = useState([]); const columns = [ { @@ -56,23 +56,34 @@ export default function ProfileWeb({ logic }: Props) { title: '已授权资源', key: 'resources', render: (_: any, record: any) => ( -
- {record.authorizedAgentIds?.map((id: string) => { - const agent = myAgents.find(a => a.id === id); - return ( - handleRevokeAgent(record.child_user_id, id)} - style={{ borderRadius: 4, background: 'var(--color-fill-secondary)', border: 'none' }} +
+
+ {record.authorizedAgentIds?.map((id: string) => { + const agent = myAgents.find(a => a.id === id); + return ( + handleRevokeAgent(record.child_user_id, [id])} + style={{ borderRadius: 4, background: 'var(--color-fill-secondary)', border: 'none', margin: 0 }} + > + 🤖 {agent?.name || '未知智能体'} + + ); + })} + {(!record.authorizedAgentIds || record.authorizedAgentIds.length === 0) ? ( + 暂无授权 + ) : ( + handleRevokeAgent(record.child_user_id, record.authorizedAgentIds)} > - 🤖 {agent?.name || '未知智能体'} - - ); - })} - {(!record.authorizedAgentIds || record.authorizedAgentIds.length === 0) && ( - 暂无授权 - )} + + + )} +
), }, @@ -104,6 +115,7 @@ export default function ProfileWeb({ logic }: Props) { icon={} onClick={() => { setSelectedMember(record); + setSelectedAgentIds(record.authorizedAgentIds || []); setAuthModalVisible(true); }} > @@ -233,24 +245,57 @@ export default function ProfileWeb({ logic }: Props) { { - handleAuthorizeAgent(selectedMember.child_user_id, selectedAgentId, 'read'); + width={520} + onOk={async () => { + // 计算新增的和移除的,但根据接口逻辑,通常是全量覆盖或者增量。 + // 这里假设 handleAuthorizeAgent 是设置最终状态,或者后端支持 resourceIds 覆盖。 + // 之前的 handleAuthorizeAgent 逻辑是直接调用 authorizeResource。 + handleAuthorizeAgent(selectedMember.child_user_id, selectedAgentIds, 'read'); setAuthModalVisible(false); - setSelectedAgentId(''); + setSelectedAgentIds([]); + }} + onCancel={() => { + setAuthModalVisible(false); + setSelectedAgentIds([]); }} - onCancel={() => setAuthModalVisible(false)} > -
选择智能体:
- +
+
+ 选择智能体 + 0 && selectedAgentIds.length < myAgents.length} + checked={selectedAgentIds.length === myAgents.length && myAgents.length > 0} + onChange={(e) => { + setSelectedAgentIds(e.target.checked ? myAgents.map(a => a.id) : []); + }} + > + 全选 + +
+ +
+ setSelectedAgentIds(vals as string[])} + > +
+ {myAgents.map(a => ( +
+ + {a.name} + +
+ ))} +
+
+ {myAgents.length === 0 && ( +
+ 暂无可选智能体 +
+ )} +
+
); diff --git a/src/pages/TeamsPage.tsx b/src/pages/TeamsPage.tsx index 8e7bb96..1201986 100644 --- a/src/pages/TeamsPage.tsx +++ b/src/pages/TeamsPage.tsx @@ -1,7 +1,8 @@ import { useEffect, useState } from 'react'; import { useTeamsPageLogic } from './TeamsPage/TeamsPageLogic'; -import TeamsPageWeb from './TeamsPage/components/TeamsPageWeb'; +import TeamsPageWebBase from './TeamsPage/components/TeamsPageWebBase'; import TeamsPageH5 from './TeamsPage/components/TeamsPageH5'; +import { useDesktopViewport } from '../hooks/useDesktopViewport'; const isMobileDevice = () => { if (typeof window === 'undefined') return false; @@ -10,6 +11,7 @@ const isMobileDevice = () => { export default function TeamsPage() { const logic = useTeamsPageLogic(); + const viewport = useDesktopViewport(); const [isMobile, setIsMobile] = useState(isMobileDevice()); useEffect(() => { @@ -20,5 +22,9 @@ export default function TeamsPage() { return () => window.removeEventListener('resize', handleResize); }, []); - return isMobile ? : ; + return isMobile ? ( + + ) : ( + + ); } diff --git a/src/pages/TeamsPage/TeamsPageLogic.ts b/src/pages/TeamsPage/TeamsPageLogic.ts index 254ba31..ffd6e2c 100644 --- a/src/pages/TeamsPage/TeamsPageLogic.ts +++ b/src/pages/TeamsPage/TeamsPageLogic.ts @@ -6,8 +6,8 @@ export function useTeamsPageLogic() { const [list, setList] = useState([]); const [active, setActive] = useState(null); const [createOpen, setCreateOpen] = useState(false); - const [inviteOpen, setInviteOpen] = useState(false); - const [lastInviteCode, setLastInviteCode] = useState(null); + const [addMemberOpen, setAddMemberOpen] = useState(false); + const [renameOpen, setRenameOpen] = useState(false); const load = async () => { const l = await TeamAPI.list(); @@ -27,14 +27,22 @@ export function useTeamsPageLogic() { setActive(await TeamAPI.detail(t.id)); }; - const handleInvite = async (v: any) => { + const handleRename = async (v: any) => { if (!active) return; - const inv = await AuthAPI.createInvite({ - teamId: active.id, - phone: v.phone || undefined, - ttlHours: Number(v.ttlHours) || 168, - }); - setLastInviteCode(inv.code); + await TeamAPI.rename(active.id, v.name); + setRenameOpen(false); + message.success('已更名'); + await load(); + setActive(await TeamAPI.detail(active.id)); + }; + + const handleAddMember = async (v: any) => { + if (!active) return; + await TeamAPI.addMember(active.id, v.phone); + setAddMemberOpen(false); + message.success('已添加'); + await load(); + setActive(await TeamAPI.detail(active.id)); }; const handleDelete = async (id: string) => { @@ -44,10 +52,11 @@ export function useTeamsPageLogic() { setActive(null); }; - const handleRemoveMember = async (id: string) => { + const handleRemoveMember = async (userId: string) => { if (!active) return; - await TeamAPI.removeMember(active.id, id); + await TeamAPI.removeMember(active.id, userId); message.success('已移除'); + await load(); setActive(await TeamAPI.detail(active.id)); }; @@ -55,17 +64,18 @@ export function useTeamsPageLogic() { list, active, createOpen, - inviteOpen, - lastInviteCode, + addMemberOpen, + renameOpen, load, handleCreate, - handleInvite, + handleRename, + handleAddMember, handleDelete, handleRemoveMember, setActive, setCreateOpen, - setInviteOpen, - setLastInviteCode, + setAddMemberOpen, + setRenameOpen, }; } diff --git a/src/pages/TeamsPage/components/TeamsPageH5.tsx b/src/pages/TeamsPage/components/TeamsPageH5.tsx index 1093bec..40f914d 100644 --- a/src/pages/TeamsPage/components/TeamsPageH5.tsx +++ b/src/pages/TeamsPage/components/TeamsPageH5.tsx @@ -1,14 +1,15 @@ import { - CopyOutlined, DeleteOutlined, - MailOutlined, + EditOutlined, PlusOutlined, TeamOutlined, + UserAddOutlined, UserOutlined, } from '@ant-design/icons'; import { Card, Button, List, Tag, Space, Popconfirm, App as AntApp, Modal, Form, Input, Empty } from 'antd'; import { TeamAPI, type Team } from '../../../api'; import type { TeamsPageLogicOutput } from '../TeamsPageLogic'; +import '../styles/teams-page-h5.css'; interface Props { logic: TeamsPageLogicOutput; @@ -20,55 +21,26 @@ export default function TeamsPageH5({ logic }: Props) { list, active, handleDelete, + handleRename, handleRemoveMember, + handleAddMember, setCreateOpen, + setRenameOpen, + setAddMemberOpen, } = logic; return (
-
-
-
+
+
+
-
- +
+ 协作组织空间
-

团队管理

-
+

团队管理

+
团队不只是成员列表,更是共享智能体、协同运营和权限分工的组织单元。
@@ -77,40 +49,23 @@ export default function TeamsPageH5({ logic }: Props) { size="middle" icon={} onClick={() => setCreateOpen(true)} - style={{ borderRadius: 10, height: 40, padding: '0 14px', fontWeight: 600, width: '100%' }} + className="teams-page-h5-create-btn" > 创建团队
-
+
{[ - { label: '团队数量', value: list.length, tone: 'rgba(8, 145, 178, 0.10)', color: 'var(--color-brand)' }, - { label: '当前成员数', value: active?.members?.length ?? 0, tone: 'rgba(14, 165, 233, 0.10)', color: 'var(--color-info)' }, - { label: '共享智能体', value: active?.agentCount ?? 0, tone: 'rgba(34, 197, 94, 0.10)', color: 'var(--color-success)' }, + { label: '团队数量', value: list.length, type: 'brand' }, + { label: '当前成员数', value: active?.members?.length ?? 0, type: 'info' }, + { label: '共享智能体', value: active?.agentCount ?? 0, type: 'success' }, ].map((item) => ( -
-
{item.label}
-
- {item.value} - +
+
{item.label}
+
+ {item.value} + 当前选中
@@ -120,38 +75,21 @@ export default function TeamsPageH5({ logic }: Props) {
{list.length > 0 && ( -
-
-
团队列表
-
点击选择一个团队
+
+
+
团队列表
+
点击选择一个团队
{list.map((item) => (
{ logic.setActive(await TeamAPI.detail(item.id)); }} - style={{ - padding: '10px 12px', - borderRadius: 10, - cursor: 'pointer', - marginBottom: 6, - background: active?.id === item.id ? 'rgba(8, 145, 178, 0.10)' : 'transparent', - color: active?.id === item.id ? 'var(--color-brand)' : 'var(--color-text-secondary)', - fontWeight: active?.id === item.id ? 600 : 500, - border: active?.id === item.id ? '1px solid rgba(8, 145, 178, 0.16)' : '1px solid transparent', - }} > -
{item.name}
-
+
{item.name}
+
{item.agentCount ?? 0} 个智能体
@@ -160,27 +98,26 @@ export default function TeamsPageH5({ logic }: Props) { )} {active ? ( - -
+ +
-
- {active.name} - {active.myRole} - {active.agentCount ?? 0} 智能体 +
+ {active.name} +
-
+
管理成员权限、邀请新伙伴。
- {(active.myRole === 'owner' || active.myRole === 'admin') && ( - - )} {active.myRole === 'owner' && ( - @@ -197,29 +134,43 @@ export default function TeamsPageH5({ logic }: Props) {
-
-
-
成员规模
-
{active.members?.length || 0}
+
+
+
成员规模
+
{active.members?.length || 0}
-
-
共享智能体
-
{active.agentCount ?? 0}
+
+
共享智能体
+
{active.agentCount ?? 0}
-
-
当前身份
-
{active.myRole}
+
+
当前身份
+
{active.myRole}
-
- 成员 ({active.members?.length || 0}) +
+
+ 成员 ({active.members?.length || 0}) +
+ {(active.myRole === 'owner' || active.myRole === 'admin') && ( + + )}
( - , @@ -240,52 +191,25 @@ export default function TeamsPageH5({ logic }: Props) { > +
} title={ - {m.name} + {m.name} {m.role} } description={ -
- {m.email} - +
+ {m.email} + 加入时间 {new Date(m.joinedAt).toLocaleDateString('zh-CN')}
@@ -317,63 +241,27 @@ export default function TeamsPageH5({ logic }: Props) { - { - logic.setInviteOpen(false); - logic.setLastInviteCode(null); - }} - width="95%" - footer={null} - destroyOnHidden - > - {logic.lastInviteCode ? ( -
-
邀请码生成成功,请发给受邀者:
- - -
- 受邀者在注册页填入此邀请码即可加入团队 -
-
- ) : ( -
- - - - - - - -
- )} + logic.setRenameOpen(false)} footer={null} width="95%" destroyOnHidden> +
+ + + + +
+
+ + logic.setAddMemberOpen(false)} footer={null} width="95%" destroyOnHidden> +
+ + + + +
-
-
-
); diff --git a/src/pages/TeamsPage/components/TeamsPageWeb.tsx b/src/pages/TeamsPage/components/TeamsPageWeb.tsx deleted file mode 100644 index 0c01440..0000000 --- a/src/pages/TeamsPage/components/TeamsPageWeb.tsx +++ /dev/null @@ -1,382 +0,0 @@ -import { - CopyOutlined, - DeleteOutlined, - MailOutlined, - PlusOutlined, - TeamOutlined, - UserOutlined, -} from '@ant-design/icons'; -import { Card, Button, List, Tag, Space, Popconfirm, App as AntApp, Modal, Form, Input, Empty } from 'antd'; -import { TeamAPI, type Team } from '../../../api'; -import type { TeamsPageLogicOutput } from '../TeamsPageLogic'; - -interface Props { - logic: TeamsPageLogicOutput; -} - -export default function TeamsPageWeb({ logic }: Props) { - const { message } = AntApp.useApp(); - const { - list, - active, - handleDelete, - handleRemoveMember, - setCreateOpen, - } = logic; - - return ( -
-
-
-
-
-
- - 协作组织空间 -
-

团队管理

-
- 团队不只是成员列表,更是共享智能体、协同运营和权限分工的组织单元。这里统一查看团队、成员和邀请状态。 -
-
- -
- -
- {[ - { label: '团队数量', value: list.length, tone: 'rgba(8, 145, 178, 0.10)', color: 'var(--color-brand)' }, - { label: '当前成员数', value: active?.members?.length ?? 0, tone: 'rgba(14, 165, 233, 0.10)', color: 'var(--color-info)' }, - { label: '共享智能体', value: active?.agentCount ?? 0, tone: 'rgba(34, 197, 94, 0.10)', color: 'var(--color-success)' }, - ].map((item) => ( -
-
{item.label}
-
- {item.value} - - 当前选中 - -
-
- ))} -
-
- -
-
-
-
团队列表
-
选择一个团队查看成员与邀请
-
- {list.length === 0 ? ( - - ) : ( - ( -
{ - logic.setActive(await TeamAPI.detail(item.id)); - }} - style={{ - padding: '10px 12px', - borderRadius: 14, - cursor: 'pointer', - marginBottom: 6, - background: active?.id === item.id ? 'rgba(8, 145, 178, 0.10)' : 'transparent', - color: active?.id === item.id ? 'var(--color-brand)' : 'var(--color-text-secondary)', - fontWeight: active?.id === item.id ? 600 : 500, - border: active?.id === item.id ? '1px solid rgba(8, 145, 178, 0.16)' : '1px solid transparent', - }} - > -
{item.name}
-
- {item.agentCount ?? 0} 个智能体 -
-
- )} - /> - )} -
- -
- {active ? ( - -
-
-
- {active.name} - {active.myRole} - {active.agentCount ?? 0} 智能体 -
-
- 管理成员权限、邀请新伙伴,并协同维护团队共享的智能体资产。 -
-
- - {(active.myRole === 'owner' || active.myRole === 'admin') && ( - - )} - {active.myRole === 'owner' && ( - { - await handleDelete(active.id); - message.success('已删除'); - }} - > - - - )} - -
- -
-
-
成员规模
-
{active.members?.length || 0}
-
-
-
共享智能体
-
{active.agentCount ?? 0}
-
-
-
当前身份
-
{active.myRole}
-
-
- -
- 成员 ({active.members?.length || 0}) -
- ( - { - await handleRemoveMember(m.id); - }} - > - - , - ] - : [] - } - > - - -
- } - title={ - - {m.name} - - {m.role} - - - } - description={ -
- {m.email} - - 加入时间 {new Date(m.joinedAt).toLocaleDateString('zh-CN')} - -
- } - /> - - )} - /> - - ) : ( - - )} -
-
- - logic.setCreateOpen(false)} - footer={null} - destroyOnHidden - > -
- - - - -
-
- - { - logic.setInviteOpen(false); - logic.setLastInviteCode(null); - }} - footer={null} - destroyOnHidden - > - {logic.lastInviteCode ? ( -
-
邀请码生成成功,请发给受邀者:
- - -
- 受邀者在注册页填入此邀请码即可加入团队 -
-
- ) : ( -
- - - - - - - -
- )} -
-
-
- -
-
- ); -} diff --git a/src/pages/TeamsPage/components/TeamsPageWebBase.tsx b/src/pages/TeamsPage/components/TeamsPageWebBase.tsx index c9f7747..a6a54de 100644 --- a/src/pages/TeamsPage/components/TeamsPageWebBase.tsx +++ b/src/pages/TeamsPage/components/TeamsPageWebBase.tsx @@ -6,6 +6,7 @@ import TeamsPageWebDetail from './TeamsPageWebDetail'; import TeamsPageWebHero from './TeamsPageWebHero'; import TeamsPageWebList from './TeamsPageWebList'; import TeamsPageWebModals from './TeamsPageWebModals'; +import '../styles/teams-page-web.css'; export interface TeamsPageWebVariantProps { logic: TeamsPageLogicOutput; @@ -23,9 +24,6 @@ export default function TeamsPageWebBase({ logic, viewport }: TeamsPageWebVarian
-
- -
); } diff --git a/src/pages/TeamsPage/components/TeamsPageWebDetail.tsx b/src/pages/TeamsPage/components/TeamsPageWebDetail.tsx index 292142f..c9b41f4 100644 --- a/src/pages/TeamsPage/components/TeamsPageWebDetail.tsx +++ b/src/pages/TeamsPage/components/TeamsPageWebDetail.tsx @@ -1,4 +1,4 @@ -import { DeleteOutlined, MailOutlined, UserOutlined } from '@ant-design/icons'; +import { DeleteOutlined, EditOutlined, UserAddOutlined, UserOutlined } from '@ant-design/icons'; import { Button, Card, Empty, List, Popconfirm, Space, Tag } from 'antd'; import type { Team } from '../../../api'; import type { TeamsPageLogicOutput } from '../TeamsPageLogic'; @@ -34,22 +34,26 @@ export default function TeamsPageWebDetail({ logic }: { logic: TeamsPageLogicOut const canManage = active.myRole === 'owner' || active.myRole === 'admin'; return ( - +
{active.name} + {canManage && ( +
管理成员权限、邀请新伙伴,并协同维护团队共享的智能体资产。
- {canManage && ( - - )} {active.myRole === 'owner' && ( handleDelete(active.id)}> - , - ] : []} +
+
成员 ({active.members?.length || 0})
+ {canManage && ( +
} - title={{member.name}{member.role}} - description={
{member.email}加入时间 {new Date(member.joinedAt).toLocaleDateString('zh-CN')}
} - /> - + 添加成员 + )} - /> +
+ +
+ {(active.members || []).map((member) => ( +
+
+
+ +
+
+
+ {member.name} + {member.role} +
+
{member.email}
+
加入时间 {new Date(member.joinedAt).toLocaleDateString('zh-CN')}
+
+
+ {canManage && member.role !== 'owner' && ( + handleRemoveMember(member.id)}> + + + )} +
+ ))} +
); } diff --git a/src/pages/TeamsPage/components/TeamsPageWebHero.tsx b/src/pages/TeamsPage/components/TeamsPageWebHero.tsx index a534e86..5796d3e 100644 --- a/src/pages/TeamsPage/components/TeamsPageWebHero.tsx +++ b/src/pages/TeamsPage/components/TeamsPageWebHero.tsx @@ -5,9 +5,9 @@ import type { TeamsPageLogicOutput } from '../TeamsPageLogic'; export default function TeamsPageWebHero({ logic }: { logic: TeamsPageLogicOutput }) { const { list, active, setCreateOpen } = logic; const stats = [ - { label: '团队数量', value: list.length, tone: 'rgba(8, 145, 178, 0.10)', color: 'var(--color-brand)' }, - { label: '当前成员数', value: active?.members?.length ?? 0, tone: 'rgba(14, 165, 233, 0.10)', color: 'var(--color-info)' }, - { label: '共享智能体', value: active?.agentCount ?? 0, tone: 'rgba(34, 197, 94, 0.10)', color: 'var(--color-success)' }, + { label: '团队数量', value: list.length, type: 'brand' }, + { label: '当前成员数', value: active?.members?.length ?? 0, type: 'info' }, + { label: '共享智能体', value: active?.agentCount ?? 0, type: 'success' }, ]; return ( @@ -34,7 +34,7 @@ export default function TeamsPageWebHero({ logic }: { logic: TeamsPageLogicOutpu
{item.label}
{item.value} - + 当前选中
diff --git a/src/pages/TeamsPage/components/TeamsPageWebList.tsx b/src/pages/TeamsPage/components/TeamsPageWebList.tsx index 1d9659a..f2ad24b 100644 --- a/src/pages/TeamsPage/components/TeamsPageWebList.tsx +++ b/src/pages/TeamsPage/components/TeamsPageWebList.tsx @@ -14,19 +14,21 @@ export default function TeamsPageWebList({ logic }: { logic: TeamsPageLogicOutpu {list.length === 0 ? ( ) : ( - ( +
+ {list.map((item) => ( - )} - /> + ))} +
)} ); diff --git a/src/pages/TeamsPage/components/TeamsPageWebModals.tsx b/src/pages/TeamsPage/components/TeamsPageWebModals.tsx index a7d3d75..04ff423 100644 --- a/src/pages/TeamsPage/components/TeamsPageWebModals.tsx +++ b/src/pages/TeamsPage/components/TeamsPageWebModals.tsx @@ -1,4 +1,3 @@ -import { CopyOutlined } from '@ant-design/icons'; import { App as AntApp, Button, Form, Input, Modal } from 'antd'; import type { TeamsPageLogicOutput } from '../TeamsPageLogic'; @@ -18,43 +17,27 @@ export default function TeamsPageWebModals({ logic }: { logic: TeamsPageLogicOut + + logic.setRenameOpen(false)} footer={null} destroyOnHidden> +
+ + + + +
+
- { - logic.setInviteOpen(false); - logic.setLastInviteCode(null); - }} - footer={null} - destroyOnHidden - > - {logic.lastInviteCode ? ( -
-
邀请码生成成功,请发给受邀者:
- - -
受邀者在注册页填入此邀请码即可加入团队
-
- ) : ( -
- - - - - - - -
- )} + logic.setAddMemberOpen(false)} footer={null} destroyOnHidden> +
+ + + + +
); diff --git a/src/pages/TeamsPage/styles/teams-page-h5.css b/src/pages/TeamsPage/styles/teams-page-h5.css new file mode 100644 index 0000000..b122ddd --- /dev/null +++ b/src/pages/TeamsPage/styles/teams-page-h5.css @@ -0,0 +1,326 @@ +.h5-page-container { + padding: 0 8px; +} + +.teams-page-h5-hero { + border-radius: 16px; + padding: 20px 16px 18px; + background: linear-gradient(135deg, rgba(255,255,255,0.98) 0%, rgba(236,253,245,0.92) 42%, rgba(239,246,255,0.96) 100%); + border: 1px solid rgba(8, 145, 178, 0.12); + box-shadow: 0 10px 24px rgba(15, 23, 42, 0.06); + margin-bottom: 16px; +} + +.teams-page-h5-hero-header { + display: flex; + justify-content: space-between; + align-items: flex-start; + gap: 12px; + flex-wrap: wrap; + margin-bottom: 16px; +} + +.teams-page-h5-badge { + display: inline-flex; + align-items: center; + gap: 6px; + padding: 4px 10px; + border-radius: 999px; + background: rgba(255,255,255,0.78); + border: 1px solid rgba(8, 145, 178, 0.10); + color: var(--color-text-secondary); + font-size: 11px; + font-weight: 600; + margin-bottom: 12px; +} + +.teams-page-h5-title { + margin-bottom: 8px; + font-size: 22px; +} + +.teams-page-h5-subtitle { + margin-top: 0; + font-size: 13px; + line-height: 1.6; +} + +.teams-page-h5-create-btn { + border-radius: 10px; + height: 40px; + padding: 0 14px; + font-weight: 600; + width: 100%; +} + +.teams-page-h5-stats-grid { + display: grid; + grid-template-columns: repeat(1, minmax(0, 1fr)); + gap: 10px; +} + +.teams-page-h5-stat-card { + border-radius: 12px; + padding: 12px 14px; + background: rgba(255,255,255,0.72); + border: 1px solid rgba(255,255,255,0.7); +} + +.teams-page-h5-stat-label { + font-size: 11px; + color: var(--color-text-secondary); + margin-bottom: 6px; +} + +.teams-page-h5-stat-row { + display: flex; + align-items: baseline; + gap: 6px; +} + +.teams-page-h5-stat-value { + font-size: 22px; + font-weight: 700; + color: var(--color-text); +} + +.teams-page-h5-stat-chip { + border-radius: 999px; + padding: 3px 6px; + font-size: 10px; + font-weight: 600; +} + +.teams-page-h5-stat-chip-brand { + background: var(--color-brand-soft); + color: var(--color-brand); +} + +.teams-page-h5-stat-chip-info { + background: var(--color-info-soft); + color: var(--color-info); +} + +.teams-page-h5-stat-chip-success { + background: var(--color-success-soft); + color: var(--color-success); +} + +.teams-page-h5-list-panel { + background: linear-gradient(180deg, rgba(255,255,255,0.98) 0%, rgba(252,252,253,1) 100%); + border: 1px solid var(--color-border); + border-radius: 16px; + padding: 12px; + margin-bottom: 16px; +} + +.teams-page-h5-list-head { + padding: 4px 6px 10px; +} + +.teams-page-h5-section-title { + font-size: 14px; + font-weight: 700; + color: var(--color-text); + margin-bottom: 4px; +} + +.teams-page-h5-section-desc { + font-size: 11px; + color: var(--color-text-secondary); +} + +.teams-page-h5-nav-item { + padding: 10px 12px; + border-radius: 10px; + cursor: pointer; + margin-bottom: 6px; + background: transparent; + color: var(--color-text-secondary); + font-weight: 500; + border: 1px solid transparent; +} + +.teams-page-h5-nav-item.active { + background: rgba(8, 145, 178, 0.10); + color: var(--color-brand); + font-weight: 600; + border: 1px solid rgba(8, 145, 178, 0.16); +} + +.teams-page-h5-nav-item-name { + font-size: 13px; + margin-bottom: 3px; +} + +.teams-page-h5-nav-item-count { + font-size: 11px; + color: var(--color-text-tertiary); +} + +.teams-page-h5-nav-item.active .teams-page-h5-nav-item-count { + color: var(--color-brand); +} + +.teams-page-h5-detail-card { + border-radius: 16px; + box-shadow: 0 6px 16px rgba(15, 23, 42, 0.045); +} + +.teams-page-web-soft-btn { + border-radius: 8px !important; +} + +.teams-page-h5-detail-card .ant-card-body { + padding: 16px !important; +} + +.teams-page-h5-detail-head { + display: flex; + flex-direction: column; + gap: 12px; + margin-bottom: 16px; +} + +.teams-page-h5-active-title-row { + display: flex; + align-items: center; + gap: 6px; + flex-wrap: wrap; + margin-bottom: 4px; +} + +.teams-page-h5-active-title { + font-size: 18px; + font-weight: 700; + color: var(--color-text); +} + +.teams-page-h5-edit-btn { + color: var(--color-text-tertiary); + padding: 0 4px; +} + +.teams-page-h5-tag { + border-radius: 999px; + margin: 0; + font-size: 11px; +} + +.teams-page-h5-tag-brand { + background: var(--color-brand-soft); + color: var(--color-brand); +} + +.teams-page-h5-tag-neutral { + background: var(--color-surface-2); + color: var(--color-text-secondary); +} + +.teams-page-h5-mini-grid { + display: grid; + grid-template-columns: repeat(1, minmax(0, 1fr)); + gap: 10px; + margin-bottom: 16px; +} + +.teams-page-h5-mini-card { + border-radius: 12px; + padding: 12px 14px; + border: 1px solid transparent; +} + +.teams-page-h5-mini-card-brand { + background: rgba(8, 145, 178, 0.06); + border: 1px solid rgba(8, 145, 178, 0.10); +} + +.teams-page-h5-mini-card-success { + background: rgba(34, 197, 94, 0.06); + border: 1px solid rgba(34, 197, 94, 0.10); +} + +.teams-page-h5-mini-card-warning { + background: rgba(249, 115, 22, 0.06); + border: 1px solid rgba(249, 115, 22, 0.10); +} + +.teams-page-h5-mini-label { + font-size: 11px; + color: var(--color-text-secondary); + margin-bottom: 6px; +} + +.teams-page-h5-mini-value { + font-size: 20px; + font-weight: 700; + color: var(--color-text); +} + +.teams-page-h5-members-title-row { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 10px; +} + +.teams-page-h5-members-title { + font-size: 14px; + font-weight: 700; + color: var(--color-text); +} + +.teams-page-h5-member-item { + padding: 10px 0; +} + +.teams-page-h5-member-avatar { + width: 36px; + height: 36px; + border-radius: 999px; + background: rgba(8, 145, 178, 0.10); + color: var(--color-brand); + display: flex; + align-items: center; + justify-content: center; +} + +.teams-page-h5-member-avatar-icon { + color: var(--color-brand); + font-size: 12px; +} + +.teams-page-h5-member-name { + font-weight: 600; + font-size: 14px; +} + +.teams-page-h5-member-desc { + display: flex; + flex-direction: column; + gap: 4px; +} + +.teams-page-h5-member-email { + font-size: 12px; +} + +.teams-page-h5-member-time { + font-size: 11px; + color: var(--color-text-tertiary); +} + +.teams-page-h5-tag-role-owner { + background: var(--color-warning-soft); + color: var(--color-warning); +} + +.teams-page-h5-tag-role-admin { + background: var(--color-info-soft); + color: var(--color-info); +} + +.teams-page-h5-tag-role-member { + background: var(--color-surface-2); + color: var(--color-text-secondary); +} diff --git a/src/pages/TeamsPage/styles/teams-page-web-detail.css b/src/pages/TeamsPage/styles/teams-page-web-detail.css index 24b7660..eadaccd 100644 --- a/src/pages/TeamsPage/styles/teams-page-web-detail.css +++ b/src/pages/TeamsPage/styles/teams-page-web-detail.css @@ -33,6 +33,8 @@ .teams-page-web-mini-card { border: 1px solid rgba(8, 145, 178, 0.1); + border-radius: 8px; + padding: 12px; } .teams-page-web-mini-brand { @@ -55,51 +57,83 @@ text-transform: capitalize; } -.teams-page-web-members-title { - margin-bottom: 14px; - font-size: 16px; +.teams-page-web-detail-card .ant-card-body { + padding: 24px !important; +} + +.teams-page-web-members-title-row { + display: flex; + justify-content: space-between; + align-items: center; + margin-top: 24px; + margin-bottom: 16px; + padding-bottom: 12px; + border-bottom: 1px solid var(--color-border-soft); +} + +.teams-page-web-member-list { + display: flex; + flex-direction: column; } .teams-page-web-member-item { - padding: 14px 0; + display: flex; + justify-content: space-between; + align-items: center; + padding: 16px 0; + border-bottom: 1px solid var(--color-border-soft); +} + +.teams-page-web-member-item:last-child { + border-bottom: none; +} + +.teams-page-web-member-info { + display: flex; + gap: 14px; + align-items: center; } .teams-page-web-member-avatar { - width: 42px; - height: 42px; - display: grid; - place-items: center; - border-radius: 999px; - background: rgba(8, 145, 178, 0.1); + width: 44px; + height: 44px; + display: flex; + align-items: center; + justify-content: center; + border-radius: 12px; + background: var(--color-brand-soft); color: var(--color-brand); + font-size: 20px; +} + +.teams-page-web-member-meta { + display: flex; + flex-direction: column; + gap: 4px; +} + +.teams-page-web-member-name-row { + display: flex; + align-items: center; + gap: 8px; } .teams-page-web-member-name { + font-size: 15px; font-weight: 700; + color: var(--color-text); } -.teams-page-web-member-desc { - display: grid; - gap: 4px; +.teams-page-web-member-email { + font-size: 13px; + color: var(--color-text-secondary); +} + +.teams-page-web-member-time { + font-size: 12px; + color: var(--color-text-tertiary); } .teams-page-web-empty-detail { align-self: center; } - -.teams-page-web-invite-label { - margin-bottom: 12px; -} - -.teams-page-web-invite-code { - font-family: ui-monospace, SFMono-Regular, Menlo, monospace; - font-size: 16px; -} - -.teams-page-web-copy-btn { - margin-top: 12px; -} - -.teams-page-web-invite-tip { - margin-top: 8px; -} diff --git a/src/pages/TeamsPage/styles/teams-page-web.css b/src/pages/TeamsPage/styles/teams-page-web.css index 4104bc3..1062425 100644 --- a/src/pages/TeamsPage/styles/teams-page-web.css +++ b/src/pages/TeamsPage/styles/teams-page-web.css @@ -44,20 +44,35 @@ font-weight: 700; } +.teams-page-web-badge .anticon { + color: var(--color-brand); +} + .teams-page-web-title { - margin-bottom: 10px; + margin-bottom: 8px; + font-size: 28px; + font-weight: 850; + color: var(--color-text); + letter-spacing: -0.02em; } .teams-page-web-subtitle { margin-top: 0; - font-size: 15px; - line-height: 1.75; + font-size: 14.5px; + line-height: 1.6; + color: var(--color-text-secondary); + max-width: 580px; } -.teams-page-web-create-btn, -.teams-page-web-soft-btn, -.teams-page-web-copy-btn { - border-radius: 12px; +.teams-page-web-create-btn { + border-radius: 14px !important; + height: 46px !important; + padding: 0 18px !important; + font-weight: 600 !important; +} + +.teams-page-web-soft-btn { + border-radius: 12px !important; } .teams-page-web-stats-grid, @@ -69,25 +84,19 @@ .teams-page-web-stats-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); - margin-top: 20px; -} - -.teams-page-web-stat-card, -.teams-page-web-mini-card { - border-radius: 18px; - padding: 16px 18px; + margin-top: 24px; + gap: 16px; /* Optimized gap for stats grid */ } .teams-page-web-stat-card { - background: rgba(255,255,255,0.72); - border: 1px solid rgba(255,255,255,0.7); + border-radius: 18px; + padding: 16px 18px; + background: rgba(255, 255, 255, 0.72); + border: 1px solid rgba(255, 255, 255, 0.7); } .teams-page-web-stat-label, -.teams-page-web-section-desc, -.teams-page-web-mini-label, -.teams-page-web-member-desc, -.teams-page-web-invite-tip { +.teams-page-web-section-desc { color: var(--color-text-secondary); font-size: 12.5px; } @@ -102,14 +111,30 @@ .teams-page-web-stat-value { color: var(--color-text); font-size: 30px; - font-weight: 800; + font-weight: 700; } .teams-page-web-stat-chip { border-radius: 999px; - padding: 4px 8px; - font-size: 12px; + padding: 4px 10px; + font-size: 11px; font-weight: 700; + letter-spacing: 0.02em; +} + +.teams-page-web-stat-chip-brand { + background: var(--color-brand-soft); + color: var(--color-brand); +} + +.teams-page-web-stat-chip-info { + background: var(--color-info-soft); + color: var(--color-info); +} + +.teams-page-web-stat-chip-success { + background: var(--color-success-soft); + color: var(--color-success); } .teams-page-web-main-grid { @@ -144,29 +169,56 @@ font-size: 15px; } +.teams-page-web-list-items { + display: flex; + flex-direction: column; + gap: 2px; +} + .teams-page-web-nav-item { width: 100%; - display: grid; - gap: 4px; border: 1px solid transparent; - border-radius: 14px; - padding: 10px 12px; - margin-bottom: 6px; + border-radius: 12px; + padding: 10px 14px; background: transparent; color: var(--color-text-secondary); cursor: pointer; text-align: left; + transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); +} + +.teams-page-web-nav-item:hover { + background: var(--color-surface-2); + color: var(--color-text); } .teams-page-web-nav-item.active { - background: rgba(8, 145, 178, 0.1); - border-color: rgba(8, 145, 178, 0.16); + background: var(--color-brand-soft); + border-color: rgba(8, 145, 178, 0.12); color: var(--color-brand); - font-weight: 700; } -.teams-page-web-nav-item small { +.teams-page-web-nav-item-content { + display: flex; + flex-direction: column; + gap: 2px; +} + +.teams-page-web-nav-item-name { + font-size: 14px; + font-weight: 600; + line-height: 1.4; +} + +.teams-page-web-nav-item-count { + font-size: 12px; color: var(--color-text-tertiary); + font-weight: 400; +} + +.teams-page-web-nav-item.active .teams-page-web-nav-item-count { + color: var(--color-brand); + opacity: 0.8; } .teams-page-web-detail-head { diff --git a/src/pages/chat/components/ChatBody.css b/src/pages/chat/components/ChatBody.css index 50b2df6..efce105 100644 --- a/src/pages/chat/components/ChatBody.css +++ b/src/pages/chat/components/ChatBody.css @@ -75,10 +75,6 @@ color: var(--color-text); } -.streaming-section { - margin-bottom: 16px; -} - .streaming-section-label { font-size: 12px; color: var(--color-text-tertiary); diff --git a/src/pages/chat/components/ChatBody.tsx b/src/pages/chat/components/ChatBody.tsx index 76f453d..858e97c 100644 --- a/src/pages/chat/components/ChatBody.tsx +++ b/src/pages/chat/components/ChatBody.tsx @@ -29,10 +29,14 @@ export default function ChatBody(props: { const [streamingReasoningExpanded, setStreamingReasoningExpanded] = useState(true); - // 当开始新的回答时,默认展开推理过程 + // 当开始新的回答时,默认展开推理过程;当正式回答开始时,自动折叠推理过程 useEffect(() => { - if (streaming.active && !streaming.answerText) { - setStreamingReasoningExpanded(true); + if (streaming.active) { + if (!streaming.answerText) { + setStreamingReasoningExpanded(true); + } else { + setStreamingReasoningExpanded(false); + } } }, [streaming.active, !!streaming.answerText]); @@ -116,11 +120,15 @@ export default function ChatBody(props: { onToggle={() => setStreamingReasoningExpanded(!streamingReasoningExpanded)} />
- {streamingReasoningExpanded && } -
-
正式回答
- {streaming.answerText ? {streaming.answerText + '▍'} : 等待输出…} -
+ {streaming.answerText && ( + <> + +
+
正式回答
+ {streaming.answerText + '▍'} +
+ + )}
{(streaming.retrieved.length > 0 || streaming.toolCalls.length > 0) && ( diff --git a/src/styles.css b/src/styles.css index e6781ea..de2aaa2 100644 --- a/src/styles.css +++ b/src/styles.css @@ -1583,7 +1583,8 @@ span.mention { } .points-mall-banner-section { - display: grid; + /* display: grid; */ + display: none; grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr); gap: 14px; margin-bottom: 12px;