import { ChatContext } from '@/app/chat-context'; import { apiInterceptors, delDialogue } from '@/client/api'; import { IChatDialogueSchema } from '@/types/chat'; import { CaretLeftOutlined, CaretRightOutlined, DeleteOutlined, ShareAltOutlined } from '@ant-design/icons'; import type { MenuProps } from 'antd'; import { Flex, Layout, Modal, Spin, Tooltip, Typography, message } from 'antd'; import copy from 'copy-to-clipboard'; import Image from 'next/image'; import { useRouter, useSearchParams } from 'next/navigation'; import React, { useContext, useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; import AppDefaultIcon from '../../common/AppDefaultIcon'; const { Sider } = Layout; const zeroWidthTriggerDefaultStyle: React.CSSProperties = { display: 'flex', alignItems: 'center', justifyContent: 'center', width: 16, height: 48, position: 'absolute', top: '50%', transform: 'translateY(-50%)', border: '1px solid #d6d8da', borderRadius: 8, right: -8, }; /** * 会话项 */ const MenuItem: React.FC<{ item: any; refresh?: any; order: React.MutableRefObject; historyLoading?: boolean; }> = ({ item, refresh, historyLoading }) => { const { t } = useTranslation(); const router = useRouter(); const searchParams = useSearchParams(); const chatId = searchParams?.get('id') ?? ''; const scene = searchParams?.get('scene') ?? ''; const { setCurrentDialogInfo } = useContext(ChatContext); // 当前活跃会话 const active = useMemo(() => { if (item.default) { return item.default && !chatId && !scene; } else { return item.conv_uid === chatId && item.chat_mode === scene; } }, [chatId, scene, item]); // 删除会话 const handleDelChat = () => { Modal.confirm({ title: t('delete_chat'), content: t('delete_chat_confirm'), centered: true, onOk: async () => { const [err] = await apiInterceptors(delDialogue(item.conv_uid)); if (err) { return; } await refresh?.(); if (item.conv_uid === chatId) { router.push(`/chat`); } }, }); }; return ( { if (historyLoading) { return; } !item.default && setCurrentDialogInfo?.({ chat_scene: item.chat_mode, app_code: item.app_code, }); localStorage.setItem( 'cur_dialog_info', JSON.stringify({ chat_scene: item.chat_mode, app_code: item.app_code, }), ); router.push(item.default ? '/chat' : `?scene=${item.chat_mode}&id=${item.conv_uid}`); }} >
{item.icon}
{item.label}
{!item.default && (
{ e.stopPropagation(); }} > { const success = copy(`${location.origin}/chat?scene=${item.chat_mode}&id=${item.conv_uid}`); message[success ? 'success' : 'error'](success ? t('copy_success') : t('copy_failed')); }} />
{ e.stopPropagation(); handleDelChat(); }} >
)}
); }; const ChatSider: React.FC<{ dialogueList: any; refresh: () => void; historyLoading: boolean; listLoading: boolean; order: React.MutableRefObject; }> = ({ dialogueList = [], refresh, historyLoading, listLoading, order }) => { const searchParams = useSearchParams(); const scene = searchParams?.get('scene') ?? ''; const { t } = useTranslation(); const { mode } = useContext(ChatContext); const [collapsed, setCollapsed] = useState(scene === 'chat_dashboard'); // 展开或收起列表按钮样式 const triggerStyle: React.CSSProperties = useMemo(() => { if (collapsed) { return { ...zeroWidthTriggerDefaultStyle, right: -16, borderRadius: '0px 8px 8px 0', borderLeft: '1px solid #d5e5f6', }; } return { ...zeroWidthTriggerDefaultStyle, borderLeft: '1px solid #d6d8da', }; }, [collapsed]); // 会话列表配置项 const items: MenuProps['items'] = useMemo(() => { const list = dialogueList[1] || []; if (list?.length > 0) { return list.map((item: IChatDialogueSchema) => ({ ...item, label: item.user_input || item.select_param, key: item.conv_uid, icon: , default: false, })); } return []; }, [dialogueList]); return ( : } zeroWidthTriggerStyle={triggerStyle} onCollapse={collapsed => setCollapsed(collapsed)} >
{t('dialog_list')}
, default: true, }} order={order} /> {!!items?.length && items.map(item => ( ))}
); }; export default ChatSider;