You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Global-sales/src/views/DesktopApp.jsx

154 lines
4.6 KiB
React

import useAuthStore from '@/stores/AuthStore'
import useConversationStore from '@/stores/ConversationStore'
import { useThemeContext } from '@/stores/ThemeContext'
import { DownOutlined } from '@ant-design/icons'
import { Avatar, Col, Dropdown, Layout, Menu, Row, Space, Typography, theme, Badge } from 'antd'
import 'dayjs/locale/zh-cn'
import { useEffect, useState } from 'react'
import { Link, NavLink, Outlet, useHref, useNavigate } from 'react-router-dom'
import '@/assets/App.css'
import AppLogo from '@/assets/logo-gh.png'
import 'react-chat-elements/dist/main.css'
const { Header, Footer, Content } = Layout
const { Title } = Typography
function DesktopApp() {
const navigate = useNavigate()
const { colorPrimary, borderRadius } = useThemeContext()
const loginUser = useAuthStore(state => state.loginUser)
const href = useHref()
useEffect(() => {
// 除了路由 /p...以外都需要登陆系统
if ((loginUser.userId === -1) && (href.indexOf('/p/') === -1)) {
navigate('/p/dingding/qrcode');
}
}, [href])
const totalNotify = useConversationStore((state) => state.totalNotify);
useEffect(() => {
if (loginUser.userId > 0) {
useConversationStore.getState().connectWebsocket(loginUser.userId);
useConversationStore.getState().fetchInitialData(loginUser.userId); // userIdStr
}
return () => {
useConversationStore.getState().disconnectWebsocket();
}
}, [])
useEffect(() => {
Notification.requestPermission();
return () => {};
}, [])
let defaultPath = '/order/follow'
if (href !== '/') {
const splitPath = href.split('/')
if (splitPath.length > 2) {
defaultPath = '/' + splitPath[1] + '/' + splitPath[2]
}
}
const {
token: { colorBgContainer },
} = theme.useToken()
/**
* 标签页标题闪烁
*/
const [isTitleVisible, setIsTitleVisible] = useState(true);
useEffect(() => {
let interval;
if (totalNotify > 0) {
interval = setInterval(() => {
document.title = isTitleVisible ? `🔔🔥💬【${totalNotify}条新消息】` : '______________';
setIsTitleVisible(!isTitleVisible);
}, 500);
} else {
document.title = '聊天式销售平台';
}
return () => clearInterval(interval);
}, [totalNotify, isTitleVisible]);
return (
<Layout>
<Header className='header' style={{ position: 'sticky', top: 0, zIndex: 2, width: '100%', background: 'white' }}>
<Row gutter={{ md: 24 }} align='middle'>
<Col flex='300px'>
<NavLink to='/'>
<img src={AppLogo} className='logo' alt='App logo' />
</NavLink>
<Title level={3}>
聊天式销售平台
</Title>
</Col>
<Col span={10}>
<Menu
mode='horizontal'
selectedKeys={[defaultPath]}
items={[
{ key: '/order/follow', label: <Link to='/order/follow'>订单跟踪</Link> },
{ key: '/order/chat', label: <Link to='/order/chat'>在线聊天
<Badge
count={totalNotify}
style={{
backgroundColor: '#52c41a',
}}
/></Link> },
{ key: '/chat/history', label: <Link to='/chat/history'>聊天记录</Link> },
]}
/>
</Col>
<Col flex='auto' style={{ color: 'white', marginBottom: '0', display: 'flex', justifyContent: 'end' }}>
<Dropdown
menu={{
items: [
{
label: <Link to='/account/profile'>个人资料</Link>,
key: '1',
},
{
type: 'divider',
},
{
label: <Link to='/p/dingding/qrcode?out'>退出</Link>,
key: '3',
},
]
}}
trigger={['click']}
>
<a onClick={(e) => e.preventDefault()} style={{ color: colorPrimary }}>
<Space><Avatar
src={loginUser.avatarUrl}>{loginUser?.username?.substring(1)}</Avatar>{loginUser.username}<DownOutlined /></Space>
</a>
</Dropdown>
</Col>
</Row>
</Header>
<Layout>
<Content
style={{
padding: 24,
margin: 0,
minHeight: 280,
background: colorBgContainer,
}}>
<Outlet />
</Content>
</Layout>
<Footer>桂林海纳国际旅行社有限公司</Footer>
</Layout>
)
}
export default DesktopApp