diff --git a/src/pages/chatConversation/ChatConversation.less b/src/pages/chatConversation/ChatConversation.less index 71ddb7f..af8983a 100644 --- a/src/pages/chatConversation/ChatConversation.less +++ b/src/pages/chatConversation/ChatConversation.less @@ -344,7 +344,7 @@ // position: fixed; left: 0; right: 0; - // bottom: -10vh; + margin-bottom: 10vh; // background: linear-gradient(to top, #f5f7fb 40%, rgba(245, 247, 251, 0)); // padding: 32px 0 28px; z-index: 20; diff --git a/src/pages/topnavbar/TopNavBar copy.js b/src/pages/topnavbar/TopNavBar copy.js new file mode 100644 index 0000000..344213d --- /dev/null +++ b/src/pages/topnavbar/TopNavBar copy.js @@ -0,0 +1,524 @@ +import React, { useState, useEffect ,useRef} from 'react' +import { history, Outlet, useModel, useDispatch, useLocation } from '@umijs/max' +import styles from './TopNavBar.less' +import { + Menu, Row, Col, + Avatar, Dropdown, Button, + Layout, theme, Divider, Tooltip, Popover +} from 'antd' +import { getPageQuery } from '@/utils/utils' +import Logo from '@/assets/logo.png' +import UserAvatar from '@/assets/boy.png' +import { + dataAnalysisStore, + conversationStore, + writingStore, + mobileStore, + assistantStore +} from '@/utils/pageConversationStore' +import { renderPageContent } from './form/RenderPageContentForm' +import { + SettingOutlined, + LogoutOutlined, + PlusOutlined, + MessageOutlined, + DeleteOutlined, + HistoryOutlined, + DownOutlined, + RobotOutlined, + BarChartOutlined, + CommentOutlined, + EditOutlined as WritingIcon, + MobileOutlined, + RightCircleOutlined, + LeftCircleOutlined, + AppstoreAddOutlined, + AppstoreOutlined, + + ApiOutlined, + DeploymentUnitOutlined, + BranchesOutlined, + DatabaseOutlined, + FileTextOutlined, +} from '@ant-design/icons'; + +const { Content, Sider } = Layout; + +function getItem(label, key, icon, children) { + return { + key, + icon, + children, + label, + }; +} + + +const menuItem = [ + { + label: 'AI助手', + key: 'aiqa', + icon: '🤖', + children: [ + { label: '智能对话', key: '/topnavbar00/aiqa/conversation', icon: }, + { label: '智能写作', key: '/topnavbar00/aiqa/writing', icon: }, + { label: '智能助理', key: '/topnavbar00/aiqa/assistant', icon: }, + { label: '数据分析', key: '/topnavbar00/aiqa/dataanalysis', icon: }, + { label: '问答移动端', key: '/topnavbar00/aiqa/mobile', icon: }, + ] + }, + { + label: '系统管理', + key: 'system', + icon: '⚙️', + children: [ + { label: '插件安装', key: '/topnavbar00/system/plugininstall', icon: }, + { label: '插件管理', key: '/topnavbar00/system/pluginmanage', icon: }, + { label: '助理配置', key: '/topnavbar00/system/assistantconfig', icon: }, + { label: '模型接入', key: '/topnavbar00/system/model', icon: }, + { label: '应用嵌入', key: '/topnavbar00/system/embed', icon: }, + { label: '工作流配置', key: '/topnavbar00/system/workflow', icon: }, + { label: '知识库管理', key: '/topnavbar00/system/knowledge', icon: }, + { label: '提示词模板管理', key: '/topnavbar00/system/prompts', icon: }, + ] + } +] + +const TopNavBar = (props) => { + const dispatch = useDispatch() + const { initialState: { menu }, setInitialState } = useModel('@@initialState') + + // 测试时候放开启用本地菜单 + window.dynamicRoute = menuItem + const dynamicRoute = window.dynamicRoute + const location = useLocation() + + const pathName = location.pathname + const [activeKey, setActiveKey] = useState(pathName ?? '/topnavbar00/aiqa/conversation') + + const [openKeys, setOpenKeys] = useState([]) + const firstLoadRef = useRef(true) + const [menuItems, setMenuItems] = useState([]) + + + const [expandedPage, setExpandedPage] = useState('conversation') + const conversationExpanded = expandedPage === 'conversation' + const writingExpanded = expandedPage === 'writing' + const dataAnalysisExpanded = expandedPage === 'dataanalysis' + const assistantExpanded = expandedPage === 'assistant' + const mobileExpanded = expandedPage === 'mobile' + + const toggleExpand = (page) => { + setExpandedPage(prev => prev === page ? null : page) + } + + // 每个页面的对话状态 + const [dataAnalysisConversations, setDataAnalysisConversations] = useState(dataAnalysisStore.getConversations()) + const [conversationConversations, setConversationConversations] = useState(conversationStore.getConversations()) + const [writingConversations, setWritingConversations] = useState(writingStore.getConversations()) + const [assistantConversations, setAssistantConversations] = useState(assistantStore.getConversations()) + const [mobileConversations, setMobileConversations] = useState(mobileStore.getConversations()) + + const [collapsed, setCollapsed] = useState(false); + const toggleCollapsed = () => setCollapsed(c => !c); + + useEffect(() => { + if (!dynamicRoute || dynamicRoute?.length === 0) return + let newList = [] + + if (dynamicRoute?.length) { + dynamicRoute?.map(item => { + newList.push({ + key: item?.key, + label: item?.label, + icon: item?.icon, + children: item?.children?.map(child => ({ + key: child?.key, + label: child?.label, + icon: child?.icon, + })) + }) + }) + + // 设置当前激活的菜单项 + const currentActiveKey = newList?.find(item => + item.children?.some(child => pathName.indexOf(child.key) !== -1) + )?.children?.find(child => pathName.indexOf(child.key) !== -1)?.key ?? '' + setActiveKey(currentActiveKey) + + // 设置默认展开的菜单 + const currentOpenKey = newList?.find(item => + item.children?.some(child => pathName.indexOf(child.key) !== -1) + )?.key ?? '' + + if (!firstLoadRef.current) { + if (currentOpenKey) { + setOpenKeys([currentOpenKey]) + } + + } else { + firstLoadRef.current = false + } + } + + setMenuItems(newList) + }, [dynamicRoute, pathName]) + + // 订阅每个页面的对话状态变化 + useEffect(() => { + const unsubscribeDataAnalysis = dataAnalysisStore.subscribe(({ conversations }) => { + setDataAnalysisConversations(conversations) + }) + + const unsubscribeConversation = conversationStore.subscribe(({ conversations }) => { + setConversationConversations(conversations) + }) + + const unsubscribeWriting = writingStore.subscribe(({ conversations }) => { + setWritingConversations(conversations) + }) + + const unsubscribeAssistant = assistantStore.subscribe(({ conversations }) => { + setAssistantConversations(conversations) + }) + + const unsubscribeMobile = mobileStore.subscribe(({ conversations }) => { + setMobileConversations(conversations) + }) + + return () => { + unsubscribeDataAnalysis() + unsubscribeConversation() + unsubscribeWriting() + unsubscribeAssistant() + unsubscribeMobile() + } + }, []) + + const setRouteActive = value => { + const curKey = value.key + setActiveKey(curKey) + history.replace(curKey) + } + + // 处理一级菜单展开/收缩 + const handleMenuGroupClick = (menuKey) => { + if (openKeys.includes(menuKey)) { + // 如果已展开,则收缩 + setOpenKeys(openKeys.filter(key => key !== menuKey)) + } else { + // 如果已收缩,则展开 + setOpenKeys([...openKeys, menuKey]) + } + } + + + + + const loginOut = async () => { + // await outLogin() + const { redirect } = getPageQuery() + if (window.location.pathname !== '/login/login' && !redirect) { + history.replace({ + pathname: '/login', + }) + + setInitialState({ currentUser: null, menu: null, menuMap: null }) + window.dynamicRoute = null + localStorage.clear() + } + } + + const handleMenuClick = (e) => { + switch (e.key) { + case 'logout': + loginOut() + break + default: + break + } + } + + const dropDownMenuItems = [ + { + label: <>退出登录, + key: 'logout' + } + ] + + const dropDownMenu = () => ( + + ) + + const { + token: { colorBgContainer, borderRadiusLG }, + } = theme.useToken(); + + const userNameContent = ( +
+
用户小智
+ 帮助中心 +
+ + 用户协议 + {/* {userInfo?.user_name_cn ? userInfo.user_name_cn : (userInfo?.user_name || '')} */} +
+ ) + + return ( +
+ {/* 头部功能 */} +
+ + {/* 左侧logo */} + + logo + AI Q&A + {/* 折叠按钮 */} + + {collapsed ? : } + + + + {/* + + 你好,欢迎使用 AI 助手 + + */} + {/* 右侧退出 */} + + + + + {/* 用户名 */} + {/* {userInfo?.user_name_cn ? userInfo.user_name_cn : (userInfo?.user_name || '')} */} + + + + + +
+ + {/* 内容 */} +
+ + +
+ {menuItems.map(item => ( +
+
handleMenuGroupClick(item.key)} + > + {/* 一级菜单 */} + {item.icon}{item.label} + {/* 一级菜单的下拉按钮 */} + {!collapsed && ( + + )} +
+ {item.children && openKeys.includes(item.key) && ( +
+ {item.children.map(child => { + // 智能对话页面 + if (child.key === '/topnavbar00/aiqa/conversation') { + return ( +
+
{ + toggleExpand('conversation') + setRouteActive(child) + + }} + > + + + {child.icon}{child.label} + {/* */} +
+ {conversationExpanded && + renderPageContent('conversation', + conversationConversations, conversationExpanded, + )} +
+ ) + } + // 智能写作页面 + if (child.key === '/topnavbar00/aiqa/writing') { + return ( +
+
{ + toggleExpand('writing') + setRouteActive(child) + }} + > + + + {child.icon}{child.label} + {/* */} +
+ {writingExpanded && renderPageContent('writing', + writingConversations, writingExpanded,)} +
+ ) + } + // 智能助理页面 + if (child.key === '/topnavbar00/aiqa/assistant') { + return ( +
+
{ + toggleExpand('assistant') + setRouteActive(child) + }} + > + + + {child.icon}{child.label} + {/* */} +
+ {assistantExpanded && renderPageContent('assistant', + assistantConversations, assistantExpanded,)} +
+ ) + } + // 数据分析页面 + if (child.key === '/topnavbar00/aiqa/dataanalysis') { + return ( +
+
{ + toggleExpand('dataanalysis') + setRouteActive(child) + }} + > + + + {child.icon}{child.label} + {/* */} +
+ {dataAnalysisExpanded && renderPageContent('dataanalysis', dataAnalysisConversations, + dataAnalysisExpanded,)} +
+ ) + } + // 问答移动端页面 + if (child.key === '/topnavbar00/aiqa/mobile') { + return ( +
+
{ + toggleExpand('mobile') + setRouteActive(child) + setCollapsed(true) // 直接收起 + }} + > + + + {child.icon}{child.label} + {/* */} +
+ {mobileExpanded && renderPageContent('mobile', mobileConversations, + mobileExpanded,)} +
+ ) + } + // 系统管理内部页面 + return ( +
setRouteActive(child)} + > + {child.icon}{child.label} +
+ ) + })} +
+ )} +
+ ))} +
+
+ + + + {/* 主题内容区域 */} + + + +
+
+
+ ) +} + +export default TopNavBar diff --git a/src/pages/topnavbar/TopNavBar.js b/src/pages/topnavbar/TopNavBar.js index a703771..bdfbf1e 100644 --- a/src/pages/topnavbar/TopNavBar.js +++ b/src/pages/topnavbar/TopNavBar.js @@ -7,6 +7,11 @@ import { getPageQuery } from '@/utils/utils' import Logo from '@/assets/logo.png' import { userInfo } from '@/utils/globalCommon' +import { + conversationStore, +} from '@/utils/pageConversationStore' +import { renderPageContent } from './form/RenderPageContentForm' + const menuItem = [ { label: '效率管理', @@ -49,7 +54,7 @@ const menuItem = [ // icon: , }, { - label: '智能对话', + label: '智能对话', key: '/topnavbar00/hrefficiency/ChatConversation', }, // { @@ -93,6 +98,20 @@ const TopNavBar = (props) => { const [activeKey, setActiveKey] = useState(pathName ?? '/topnavbar00/home') const [menuItems, setMenuItems] = useState([]) + + + const [expandedPage, setExpandedPage] = useState('conversation') + const conversationExpanded = expandedPage === 'conversation' + + const toggleExpand = (page) => { + setExpandedPage(prev => prev === page ? null : page) + } + const [conversationConversations, setConversationConversations] = useState(conversationStore.getConversations()) + + const [collapsed, setCollapsed] = useState(false); + const toggleCollapsed = () => setCollapsed(c => !c); + + useEffect(() => { if (!dynamicRoute || dynamicRoute?.length === 0) return let newList = [] @@ -102,7 +121,12 @@ const TopNavBar = (props) => { newList.push({ key: item?.key, label: item?.label, - icon: item?.icon + icon: item?.icon, + children: item?.children?.map(child => ({ + key: child?.key, + label: child?.label, + // icon: child?.icon, + })) }) }) @@ -112,6 +136,20 @@ const TopNavBar = (props) => { setMenuItems(newList) }, [dynamicRoute]) + + useEffect(() => { + const unsubscribeConversation = conversationStore.subscribe(({ conversations }) => { + setConversationConversations(conversations) + }) + + return () => { + unsubscribeConversation() + } + }, []) + + + + const setRouteActive = value => { const curKey = value.key const activeKeys = menuItems?.filter(item => curKey.indexOf(item.key) !== -1)[0]?.key ?? '' @@ -172,7 +210,6 @@ const TopNavBar = (props) => { {/* logo - setRouteActive(value)} /> */} @@ -188,9 +225,12 @@ const TopNavBar = (props) => { + {/* 修改:当路由为智能对话页时,渲染历史会话组件(renderPageContent),其它路由不变 */}
-
+ {/* {renderPageContent('conversation', conversationConversations, conversationExpanded)} */} + + {/* 底部版权信息 */}
{ + if (!expanded) return null + + const storeMap = { + dataanalysis: { store: dataAnalysisStore, path: '/topnavbar00/hrefficiency/dataanalysis' }, + conversation: { store: conversationStore, path: '/topnavbar00/hrefficiency/ChatConversation' }, + writing: { store: writingStore, path: '/topnavbar00/hrefficiency/writing' }, + assistant: { store: assistantStore, path: '/topnavbar00/hrefficiency/assistant' }, + mobile: { store: mobileStore, path: '/topnavbar00/hrefficiency/mobile' } + } + + // 创建新对话 - 根据页面类型 + const createNewConversation = (pageType) => { + switch (pageType) { + case 'dataanalysis': + dataAnalysisStore.createNewConversation() + history.replace('/topnavbar00/hrefficiency/dataanalysis') + break + case 'conversation': + conversationStore.createNewConversation() + history.replace('/topnavbar00/hrefficiency/ChatConversation') + break + case 'writing': + writingStore.createNewConversation() + history.replace('/topnavbar00/hrefficiency/writing') + break + case 'assistant': + assistantStore.createNewConversation() + history.replace('/topnavbar00/hrefficiency/assistant') + break + case 'mobile': + mobileStore.createNewConversation() + history.replace('/topnavbar00/hrefficiency/mobile') + break + default: + break + } + } + + // 删除对话 - 根据页面类型 + const deleteConversation = (conversationId, pageType) => { + switch (pageType) { + case 'dataanalysis': + dataAnalysisStore.deleteConversation(conversationId) + break + case 'conversation': + conversationStore.deleteConversation(conversationId) + break + case 'writing': + writingStore.deleteConversation(conversationId) + break + case 'assistant': + assistantStore.deleteConversation(conversationId) + break + case 'mobile': + mobileStore.deleteConversation(conversationId) + break + default: + break + } + } + + + // 切换对话 - 根据页面类型 + const switchConversation = (conversationId, pageType) => { + switch (pageType) { + case 'dataanalysis': + dataAnalysisStore.switchConversation(conversationId) + history.replace('/topnavbar00/hrefficiency/dataanalysis') + break + case 'conversation': + conversationStore.switchConversation(conversationId) + history.replace('/topnavbar00/hrefficiency/ChatConversation') + break + case 'writing': + writingStore.switchConversation(conversationId) + history.replace('/topnavbar00/hrefficiency/writing') + break + case 'assistant': + assistantStore.switchConversation(conversationId) + history.replace('/topnavbar00/hrefficiency/assistant') + break + case 'mobile': + mobileStore.switchConversation(conversationId) + history.replace('/topnavbar00/hrefficiency/mobile') + break + default: + break + } + } + + + + return ( +
+
+
+ + 历史会话 + + {/* 新对话 */} + +
+ +
+ {conversations.map((conversation) => ( +
switchConversation(conversation.id, pageType)} + > +
+
+ + + {conversation.title} + +
+
+ {conversation.lastUpdate.toLocaleDateString()} +
+
+ +
+ +
+
+ ))} +
+
+
+ ) +} + +export default renderPageContent \ No newline at end of file diff --git a/src/pages/topnavbar/form/RenderPageContentForm.less b/src/pages/topnavbar/form/RenderPageContentForm.less new file mode 100644 index 0000000..d47b548 --- /dev/null +++ b/src/pages/topnavbar/form/RenderPageContentForm.less @@ -0,0 +1,782 @@ +// .layoutContainer { +// height: 100vh; +// background: #fff; +// display: flex; +// flex-direction: column; +// overflow-y: auto; + +// // 顶部栏 +// .tabBarHeader { +// // background: rgba(255, 255, 255, 0.95);135deg, #667eea 0%, #764ba2 100% +// padding: 0; +// width: 100%; +// height: 65px; +// margin-bottom: -4px; +// border-bottom: 1px solid rgba(0, 0, 0, 0.06); +// box-shadow: 0 2px 4px rgba(31, 35, 41, 0.04); +// background: +// linear-gradient(120deg, #ffffff 0%, #f6f9ff 55%, #fff 100%); + +// .tabBarRow { +// padding: 0 24px; +// height: 100%; +// display: flex; +// align-items: center; +// // position: relative; + +// .tabBarLeft { +// display: flex; +// justify-content: flex-start; +// flex-wrap: nowrap; +// align-items: center; + +// .leftLogo { +// width: 40px; +// height: 40px; +// margin-right: 11px; +// margin-top: -8px; +// border-radius: 8px; +// } + +// .leftTopText { +// font-size: 24px; +// height: 40px; +// font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; +// font-weight: 600; +// background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); +// -webkit-background-clip: text; +// -webkit-text-fill-color: transparent; +// background-clip: text; +// letter-spacing: 0.02em; +// } + +// .collapseButton { +// color: #8f8f8f; +// margin-left: 10px; +// margin-top: -8px; +// font-size: 20px; +// transition: none !important; + +// :global { +// .ant-layout-sider { +// transition: none !important; +// } +// } + +// &:hover { +// color: #000; +// // cursor:pointer; +// cursor: pointer; +// } +// } +// } + +// .tabBarRight { +// text-align: right; +// display: flex; +// justify-content: flex-end; +// flex-wrap: nowrap; +// align-items: center; + +// .tabBarRightAvaTor { +// margin-right: 2px; +// margin-top: -1px; +// border: 2px solid rgba(102, 126, 234, 0.2); +// } + +// .tabBarRightName { +// margin-right: 0px; +// font-weight: 500; +// color: #333; +// } + +// .tabBarRightBtn { +// height: 40px; +// width: 40px; +// // border-radius: 6px; +// background: transparent; +// // background: rgba(102, 126, 234, 0.1); +// border-color: transparent; +// // border: 1px solid rgba(102, 126, 234, 0.2); +// color: #666; +// font-size: 18px; + +// &:hover { +// background: transparent; +// border-color: transparent; +// } +// } + +// .userNameContent { +// width: 33px; +// height: 33px; +// background-color: #fff; +// box-shadow: transparent; +// } +// } +// } +// } + +// // 内容 +// .contentMain { +// flex: 1; +// display: flex; +// overflow: hidden; +// background: rgba(255, 255, 255); + +// .sider { +// background: rgba(255, 255, 255); +// overflow-y: auto; +// overflow-x: hidden; + +// &::-webkit-scrollbar { +// width: 6px; +// } + +// &::-webkit-scrollbar-track { +// background: rgba(255, 255, 255); +// } + +// &::-webkit-scrollbar-thumb { +// background: rgba(255, 255, 255); + +// &:hover { +// background: rgba(255, 255, 255); +// } +// } + +// .sideMenu { +// border-right: none; +// background-color: transparent; +// padding: 16px 0; + +// :global(.ant-menu-submenu) { +// margin: 4px 12px; +// border-radius: 8px; +// overflow: hidden; + +// .ant-menu-submenu-title { +// height: 48px; +// line-height: 48px; +// border-radius: 8px; +// margin: 0; +// font-weight: 500; +// color: #333; +// transition: all 0.3s ease; + +// &:hover { +// background: rgba(255, 255, 255); +// color: #667eea; +// } + +// .ant-menu-submenu-arrow { +// color: #667eea; +// } +// } + +// &.ant-menu-submenu-open>.ant-menu-submenu-title { +// background: rgba(255, 255, 255); +// color: #667eea; +// } +// } + +// :global(.ant-menu-item) { +// margin: 2px 12px; +// border-radius: 6px; +// height: 40px; +// line-height: 40px; +// padding-left: 24px !important; +// font-size: 14px; +// transition: all 0.3s ease; + +// &:hover { +// background: rgba(255, 255, 255); +// color: #667eea; +// } + +// &.ant-menu-item-selected { +// background: rgba(255, 255, 255); +// color: #667eea; +// font-weight: 500; +// border-right: 3px solid #667eea; +// } +// } + +// :global(.ant-menu-submenu-inline > .ant-menu) { +// background: rgba(255, 255, 255, 0.5); +// border-radius: 8px; +// margin: 8px 0; +// } +// } + +// // 自定义菜单样式 +// .customMenu { +// padding: 8px 0 16px 0; +// margin: 10px 0px 0px 9px; +// position: relative; +// border: 1px solid rgba(0, 0, 0, 0.06); +// border-radius: 8px; +// background: +// linear-gradient(#ffffff, #ffffff) padding-box, +// linear-gradient(135deg, rgba(102, 126, 234, 0.25), rgba(118, 75, 162, 0.25)) border-box; +// box-shadow: 0 2px 6px rgba(0, 0, 0, 0.04); +// backdrop-filter: blur(2px); + +// &:before { +// content: ''; +// position: absolute; +// left: 0; +// top: 6px; +// bottom: 6px; +// width: 3px; +// border-radius: 2px; +// // background: linear-gradient(180deg, #667eea, #764ba2); +// } + +// .menuGroup { +// margin-bottom: 16px; + +// .menuGroupTitle { +// display: flex; +// align-items: center; +// justify-content: space-between; +// padding: 12px 16px; +// font-weight: 500; +// color: #030303; +// cursor: pointer; +// transition: background-color 0.2s ease; + +// &:hover { +// background-color: #fafafa; +// } + +// .menuGroupLabel { +// flex: 1; +// font-size: 16px; +// text-align: center; + +// &:hover { +// background-color: #fafafa; +// } +// } + +// .menuGroupArrow { +// font-size: 12px; +// color: #999; +// transition: transform 0.3s ease; +// } +// } + +// .menuGroupItems { + +// .menuItem { +// display: flex; +// align-items: center; +// text-align: center; +// padding: 8px 16px 8px 16px; +// margin: 2px 12px; +// border-radius: 6px; +// height: 40px; +// line-height: 24px; +// font-size: 13px; +// color: #030303; +// font-weight: 500; +// cursor: pointer; +// transition: all 0.3s ease; + +// &:hover { +// background-color: #fafafa; +// color: #030303; +// } + +// &.active { +// background-color: #fafafa; +// color: #030303; +// font-weight: 500; +// } +// } + +// .assistantMenuItem { +// display: flex; +// align-items: center; +// justify-content: space-between; +// padding: 8px 16px 8px 16px; +// margin: 2px 12px; +// border-radius: 6px; +// height: 40px; +// line-height: 24px; +// font-size: 14px; +// color: #333; +// cursor: pointer; +// transition: all 0.3s ease; + +// &:hover { +// background: rgba(102, 126, 234, 0.08); +// color: #667eea; +// } + +// &.active { +// background: linear-gradient(135deg, rgba(102, 126, 234, 0.15) 0%, rgba(118, 75, 162, 0.15) 100%); +// color: #667eea; +// font-weight: 500; +// border-right: 3px solid #667eea; +// // box-shadow: 0 2px 8px rgba(102, 126, 234, 0.2); +// } + +// .assistantArrow { +// font-size: 12px; +// color: #999; +// transition: transform 0.3s ease; + +// &.expanded { +// transform: rotate(180deg); +// } +// } +// } + +// // 页面菜单项样式 +// .pageMenuItem { +// display: flex; +// align-items: center; +// position: relative; +// justify-content: center; +// padding: 10px 14px; +// cursor: pointer; +// transition: all 0.2s ease; +// border-radius: 6px; +// margin: 4px 8px; +// font-size: 12px; + + +// &:hover { +// background: #f5f5f5; +// } + +// &.active { +// background: #f5f5f5; +// } + +// span { +// flex: 1; +// text-align: center; +// } + +// .pageArrow { +// margin-left: auto; +// font-size: 12px; +// color: #999; +// transition: transform 0.3s ease; + +// &.expanded { +// transform: rotate(180deg); +// } +// } +// } +// } +// } +// } + +// // 智能助理展开内容样式 +// .assistantExpandedContent { +// margin: 0 12px 16px 16px; +// background: rgba(255, 255, 255, 0.8); +// border-radius: 8px; +// padding: 12px; + +// .assistantHeader { +// margin-bottom: 8px; + +// } + +// // .conversationsList { +// // // .conversationsTitle { +// // // display: flex; +// // // align-items: center; +// // // width: 100%; +// // // gap: 8px; +// // // font-size: 12px; +// // // font-weight: 500; +// // // // color: #666; +// // // color: pink; +// // // margin-bottom: 8px; +// // // padding: 0 4px; + +// // // :global { +// // // .ant-btn-primary { +// // // background: #666 !important; +// // // } +// // // } + +// // // .anticon { +// // // color: #999; +// // // font-size: 14px; +// // // } +// // // } + +// // .conversationsContainer { +// // max-height: 200px; +// // overflow-y: auto; +// // padding-right: 4px; + +// // // 自定义滚动条样式 +// // &::-webkit-scrollbar { +// // width: 4px; +// // } + +// // &::-webkit-scrollbar-track { +// // background: #f1f1f1; +// // border-radius: 2px; +// // } + +// // &::-webkit-scrollbar-thumb { +// // background: #c1c1c1; +// // border-radius: 2px; +// // } + +// // &::-webkit-scrollbar-thumb:hover { +// // background: #a8a8a8; +// // } + +// // .conversationItem { +// // display: flex; +// // align-items: center; +// // justify-content: space-between; +// // padding: 8px; +// // margin-bottom: 6px; +// // border-radius: 6px; +// // cursor: pointer; +// // transition: all 0.2s ease; +// // border: 1px solid transparent; + +// // &:hover { +// // background: #f5f5f5; +// // border-color: #e6e6e6; + +// // .conversationActions { +// // opacity: 1; +// // } +// // } + +// // &.active { +// // background: #e6f7ff; +// // border-color: #91d5ff; + +// // .conversationTitle .titleText { +// // color: #1890ff; +// // font-weight: 500; +// // } +// // } + +// // .conversationContent { +// // flex: 1; +// // min-width: 0; + +// // .conversationTitle { +// // display: flex; +// // align-items: center; +// // gap: 6px; +// // margin-bottom: 2px; + +// // .conversationIcon { +// // color: #52c41a; +// // font-size: 12px; +// // } + +// // .titleText { +// // font-size: 13px; +// // color: #333; +// // overflow: hidden; +// // text-overflow: ellipsis; +// // white-space: nowrap; +// // max-width: 100px; +// // } +// // } + +// // .conversationTime { +// // font-size: 11px; +// // color: #999; +// // } +// // } + +// // .conversationActions { +// // opacity: 0; +// // transition: opacity 0.2s ease; + +// // .ant-btn { +// // padding: 2px; +// // height: 20px; +// // width: 20px; +// // font-size: 12px; + +// // &:hover { +// // background: rgba(0, 0, 0, 0.05); +// // } +// // } +// // } +// // } +// // } +// // } +// } +// } + +// .contentLayout { +// flex: 1; +// background: transparent; +// overflow: hidden; + +// .content { +// height: 100%; +// padding: 8px 12px 8px 12px; +// background-color: #fff; +// overflow-y: auto; +// overflow-x: hidden; + +// &::-webkit-scrollbar { +// width: 8px; +// } + +// &::-webkit-scrollbar-track { +// // background: rgba(255, 255, 255, 0.1); +// border-radius: 4px; +// } + +// &::-webkit-scrollbar-thumb { +// // background: rgba(102, 126, 234, 0.3); +// border-radius: 4px; + +// &:hover { +// // background: rgba(102, 126, 234, 0.5); +// } +// } +// } +// } +// } +// } + + +// 用户头像悬浮样式 - 强制覆盖 Ant Design 默认样式 +:global(.ant-popover) { + .ant-popover-title { + width: 150px !important; + min-width: 150px !important; + max-width: 150px !important; + text-align: center !important; + text-align-last: center !important; + text-align: center !important; + } + + .ant-popover-inner-content { + color: rgba(0, 0, 0, 0.88) !important; + justify-content: center !important; + align-items: center !important; + display: flex !important; + flex-direction: column !important; + padding: 10px !important; + text-align: center !important; + text-align-last: center !important; + text-align: center !important; + } + + // 确保所有文本内容都居中 + .ant-popover-inner-content p { + text-align: center !important; + margin: 0 !important; + padding: 2px 0 !important; + width: 100% !important; + text-align: center; + } + + // 强制覆盖内容区域宽度和居中 + .ant-popover-content { + min-width: 150px !important; + max-width: 150px !important; + text-align: center !important; + } + + .ant-popover-inner { + min-width: 150px !important; + max-width: 150px !important; + text-align: center !important; + } +} + +.pageExpandedContent { + margin: 4px 14px 4px 12px; + padding: 6px 10px 8px 10px; + width: 12vw; + background: #fff; + display: flex; + border: 1px solid #e5e5e5; // 新增外边框 + border-radius: 6px; + + .newChatBtn { + // margin-left: auto; + display: inline-flex; + align-items: center; + justify-content: center; + height: 20px; + width: 20px; + border-radius: 6px; + + } + + .conversationsList { + .conversationsTitle { + display: flex; + align-items: center; + gap: 6px; + width: 46vw; + font-size: 13px; + font-weight: 500; + color: #666; + margin-bottom: 8px; + padding: 0 2px; + + :global { + .ant-btn-primary { + background: rgba(153, 153, 153, 0.5) !important; + box-shadow: none !important; // 阴影 + + &:hover { + background: rgba(153, 153, 153, 0.8) !important; + } + } + } + + .anticon { + color: #999; + font-size: 12px; + } + } + + .conversationsContainer { + max-height: 200px; + overflow-y: auto; + + // 自定义滚动条样式 + &::-webkit-scrollbar { + width: 4px; + } + + &::-webkit-scrollbar-track { + background: #f1f1f1; + border-radius: 2px; + } + + &::-webkit-scrollbar-thumb { + background: #c1c1c1; + border-radius: 2px; + } + + &::-webkit-scrollbar-thumb:hover { + background: #a8a8a8; + } + } + + .conversationItem { + display: flex; + align-items: center; + justify-content: space-between; + padding: 8px 10px; + margin-bottom: 6px; + width: 10.5vw; + border-radius: 6px; + cursor: pointer; + transition: all 0.2s ease; + border: 1px solid transparent; + + &:hover { + background: #f0f0f0; + + .conversationActions { + opacity: 1; + } + } + + &.active { + background: #e6f7ff; + border-color: #91d5ff; + + .conversationTitle .titleText { + color: #1890ff; + font-weight: 500; + } + } + + .conversationContent { + flex: 1; + min-width: 0; + + .conversationTitle { + display: flex; + align-items: center; + gap: 6px; + margin-bottom: 2px; + + .conversationIcon { + color: #1890ff; + font-size: 12px; + } + + .titleText { + font-size: 12px; + color: #333; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + max-width: 100px; + } + } + + .conversationTime { + font-size: 11px; + color: #999; + } + } + + .conversationActions { + opacity: 0; + transition: opacity 0.2s ease; + display: flex; + gap: 2px; + + .ant-btn { + padding: 2px; + height: 20px; + width: 20px; + font-size: 10px; + + &:hover { + background: rgba(0, 0, 0, 0.05); + } + } + } + } + } +} + +// 智能助理特殊样式(保持兼容性) +.assistantMenuItem { + @extend .pageMenuItem; +} + +.assistantExpandedContent { + @extend .pageExpandedContent; +} + +.assistantHeader { + @extend .pageHeader; +} + + +:global { + .userLink { + color: #000; + text-decoration: none; + transition: color .2s; + + &:hover { + color: #1677ff; // 悬停颜色 + } + } +} \ No newline at end of file