diff --git a/src/views/AuthApp.jsx b/src/views/AuthApp.jsx index d1186dc..4930801 100644 --- a/src/views/AuthApp.jsx +++ b/src/views/AuthApp.jsx @@ -2,7 +2,15 @@ import ErrorBoundary from '@/components/ErrorBoundary' import useAuthStore from '@/stores/AuthStore' import useConversationStore from '@/stores/ConversationStore' import { useThemeContext } from '@/stores/ThemeContext' -import { App as AntApp, ConfigProvider, Empty, theme } from 'antd' +import { + App as AntApp, + ConfigProvider, + Empty, + message, + FloatButton, + theme, +} from 'antd' +import { BugOutlined } from '@ant-design/icons' import zhLocale from 'antd/locale/zh_CN' import 'dayjs/locale/zh-cn' import { useEffect } from 'react' @@ -15,44 +23,56 @@ import '@/assets/App.css' import 'react-chat-elements/dist/main.css' function AuthApp() { - const navigate = useNavigate() + const [messageApi, contextHolder] = message.useMessage() + const { colorPrimary, borderRadius } = useThemeContext() - const loginUser = useAuthStore(state => state.loginUser) + const loginUser = useAuthStore((state) => state.loginUser) const href = useHref() - const [connectWebsocket, fetchInitialData, disconnectWebsocket ] = useConversationStore((state) => [ - state.connectWebsocket, - state.fetchInitialData, - state.disconnectWebsocket, - ]); + const [connectWebsocket, fetchInitialData, disconnectWebsocket] = + useConversationStore((state) => [ + state.connectWebsocket, + state.fetchInitialData, + state.disconnectWebsocket, + ]) + useEffect(() => { - if (!("Notification" in window)) { + if (!('Notification' in window)) { // alert("This browser does not support desktop notification"); } else { - Notification.requestPermission(); + Notification.requestPermission() } if (loginUser.userId > 0) { - appendRequestHeader('X-User-Id', loginUser.userId); - loadPageSpy(loginUser.username); - connectWebsocket(loginUser.userId); - fetchInitialData(loginUser.userId); + appendRequestHeader('X-User-Id', loginUser.userId) + loadPageSpy(loginUser.username) + connectWebsocket(loginUser.userId) + fetchInitialData(loginUser.userId) } return () => { - disconnectWebsocket(); - }; + disconnectWebsocket() + } }, []) + const uploadLog = () => { + if (window.$pageSpy) { + window.$pageSpy.triggerPlugins('onOfflineLog', 'upload') + messageApi.info('Success') + } else { + messageApi.error('Failure') + } + } + // 除了路由 /p...以外都需要登陆系统 - const needToLogin = (loginUser.userId === -1) && (href.indexOf('/p/') === -1) + const needToLogin = loginUser.userId === -1 && href.indexOf('/p/') === -1 useEffect(() => { if (needToLogin) { navigate('/p/dingding/login?origin_url=' + href) } - }, [href]) + }, [href]) return ( }> + renderEmpty={() => } + > + + } onClick={() => uploadLog()} /> + + + {contextHolder} {needToLogin ? <>login... : } - - logo -
+ + logo +

销售平台

Sales CRM

Haina travel global sales CRM system

-
- - +
@@ -87,7 +127,7 @@ function AuthApp() { - ); + ) } export default AuthApp diff --git a/src/views/DesktopApp.jsx b/src/views/DesktopApp.jsx index 430d28b..18991fc 100644 --- a/src/views/DesktopApp.jsx +++ b/src/views/DesktopApp.jsx @@ -2,7 +2,18 @@ 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 { + 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 } from 'react-router-dom' @@ -10,9 +21,8 @@ import { Link, NavLink, Outlet, useHref } from 'react-router-dom' import '@/assets/App.css' import AppLogo from '@/assets/highlights_travel_300_300.png' import 'react-chat-elements/dist/main.css' -import ReloadPrompt from './ReloadPrompt'; -import ClearCache from './ClearCache'; -import PageSpy from './PageSpy'; +import ReloadPrompt from './ReloadPrompt' +import ClearCache from './ClearCache' import { BUILD_VERSION, BUILD_DATE } from '@/config' @@ -20,9 +30,8 @@ const { Header, Footer, Content } = Layout const { Title } = Typography function DesktopApp() { - const { colorPrimary } = useThemeContext() - const loginUser = useAuthStore(state => state.loginUser) + const loginUser = useAuthStore((state) => state.loginUser) const href = useHref() @@ -31,7 +40,7 @@ function DesktopApp() { let defaultPath = '/order/follow' if (href !== '/') { - const splitPath = href.split('/'); + const splitPath = href.split('/') if (splitPath.length > 2) { defaultPath = '/' + splitPath[1] + '/' + splitPath[2] } @@ -44,46 +53,60 @@ function DesktopApp() { /** * 标签页标题闪烁 */ - const [isTitleVisible, setIsTitleVisible] = useState(true); + const [isTitleVisible, setIsTitleVisible] = useState(true) useEffect(() => { - let interval; + let interval if (totalNotify > 0) { if ('setAppBadge' in navigator) { - navigator.setAppBadge(totalNotify).catch((error) => {}); + navigator.setAppBadge(totalNotify).catch((error) => {}) } interval = setInterval(() => { - document.title = isTitleVisible ? `🔔🔥💬【${totalNotify}条新消息】` : '______________'; - setIsTitleVisible(!isTitleVisible); - }, 500); + document.title = isTitleVisible + ? `🔔🔥💬【${totalNotify}条新消息】` + : '______________' + setIsTitleVisible(!isTitleVisible) + }, 500) } else { - document.title = '销售平台'; + document.title = '销售平台' if ('clearAppBadge' in navigator) { - navigator.clearAppBadge().catch((error) => {}); + navigator.clearAppBadge().catch((error) => {}) } } - return () => clearInterval(interval); - }, [totalNotify, isTitleVisible]); + return () => clearInterval(interval) + }, [totalNotify, isTitleVisible]) return ( -
- - - - App logo +
+ + + + App logo 销售平台 订单跟踪 }, + { + key: '/order/follow', + label: 订单跟踪, + }, { key: '/order/chat', label: ( - + 在线聊天 0 ? totalNotify : undefined} @@ -94,18 +117,32 @@ function DesktopApp() { ), }, - { key: '/callcenter/call', label: 语音通话 }, - { key: '/chat/history', label: 聊天记录 }, + { + key: '/callcenter/call', + label: 语音通话, + }, + { + key: '/chat/history', + label: 聊天记录, + }, ]} /> - + 个人资料, + label: 个人资料, key: '1', }, { type: 'divider' }, @@ -114,15 +151,21 @@ function DesktopApp() { { label: , key: 'clearcache' }, { type: 'divider' }, { - label: 退出, + label: 退出, key: '3', }, ], }} - trigger={['click']}> - e.preventDefault()} style={{ color: colorPrimary }}> + trigger={['click']} + > + e.preventDefault()} + style={{ color: colorPrimary }} + > - {loginUser?.username?.substring(1)} + + {loginUser?.username?.substring(1)} + {loginUser.username} @@ -138,13 +181,16 @@ function DesktopApp() { margin: 0, minHeight: 280, background: colorBgContainer, - }}> + }} + > -
桂林海纳国际旅行社有限公司 Version: {BUILD_VERSION}({BUILD_DATE}){' '}
+
+ 桂林海纳国际旅行社有限公司 Version: {BUILD_VERSION}({BUILD_DATE}) +
- ); + ) } export default DesktopApp diff --git a/src/views/MobileApp.jsx b/src/views/MobileApp.jsx index 6714d7a..b2a74ce 100644 --- a/src/views/MobileApp.jsx +++ b/src/views/MobileApp.jsx @@ -1,59 +1,74 @@ -import { useEffect } from 'react'; -import '@/assets/App.css'; -import AppLogo from '@/assets/highlights_travel_300_300.png'; -import { useThemeContext } from '@/stores/ThemeContext'; -import useAuthStore from '@/stores/AuthStore'; -import { Layout, Typography, theme, Space, Avatar, Dropdown, Flex } from 'antd'; -import { DownOutlined } from '@ant-design/icons'; -import { NavLink, Outlet, Link } from 'react-router-dom'; -import ReloadPrompt from './ReloadPrompt'; -import ClearCache from './ClearCache'; -import PageSpy from './PageSpy'; +import { useEffect } from 'react' +import '@/assets/App.css' +import AppLogo from '@/assets/highlights_travel_300_300.png' +import { useThemeContext } from '@/stores/ThemeContext' +import useAuthStore from '@/stores/AuthStore' +import { Layout, Typography, theme, Space, Avatar, Dropdown, Flex } from 'antd' +import { DownOutlined } from '@ant-design/icons' +import { NavLink, Outlet, Link } from 'react-router-dom' +import ReloadPrompt from './ReloadPrompt' +import ClearCache from './ClearCache' -import { BUILD_VERSION } from '@/config'; +import { BUILD_VERSION } from '@/config' -const { Header, Footer, Content } = Layout; -const { Title } = Typography; +const { Header, Footer, Content } = Layout +const { Title } = Typography function MobileApp() { - const { colorPrimary, borderRadius } = useThemeContext(); - const loginUser = useAuthStore((state) => state.loginUser); + const { colorPrimary, borderRadius } = useThemeContext() + const loginUser = useAuthStore((state) => state.loginUser) const { token: { colorBgContainer }, - } = theme.useToken(); + } = theme.useToken() useEffect(() => { const handleLoad = () => { - const isPWAInstalled = window.matchMedia('(display-mode: window-controls-overlay)').matches || window.matchMedia('(display-mode: standalone)').matches; - const isStandalone = navigator.standalone || window.navigator.standalone; + const isPWAInstalled = + window.matchMedia('(display-mode: window-controls-overlay)').matches || + window.matchMedia('(display-mode: standalone)').matches + const isStandalone = navigator.standalone || window.navigator.standalone if (isPWAInstalled || isStandalone) { - document.getElementById('install-button').disabled = true; + document.getElementById('install-button').disabled = true } else { - document.getElementById('about-dialog').showModal(); + document.getElementById('about-dialog').showModal() window.addEventListener('beforeinstallprompt', (e) => { - e.preventDefault(); + e.preventDefault() - document.getElementById('about-dialog').addEventListener('close', () => { - if (document.getElementById('about-dialog').returnValue === 'install') { - e.prompt(); - } - }); - }); + document + .getElementById('about-dialog') + .addEventListener('close', () => { + if ( + document.getElementById('about-dialog').returnValue === + 'install' + ) { + e.prompt() + } + }) + }) } - }; + } - window.addEventListener('load', handleLoad); - return () => window.removeEventListener('load', handleLoad); - }, []); + window.addEventListener('load', handleLoad) + return () => window.removeEventListener('load', handleLoad) + }, []) return ( -
+
- - App logo + + App logo {!('Notification' in window) && 🔕} @@ -64,17 +79,21 @@ function MobileApp() { { type: 'divider' }, { label: , key: 'clearcache' }, { type: 'divider' }, - { label: 退出, key: '3' }, + { label: 退出, key: '3' }, { type: 'divider' }, { label: <>v{BUILD_VERSION}, key: 'BUILD_VERSION' }, - { type: 'divider' }, - { label: , key: 'pagespy' }, ], }} - trigger={['click']}> - e.preventDefault()} style={{ color: colorPrimary }}> + trigger={['click']} + > + e.preventDefault()} + style={{ color: colorPrimary }} + > - {loginUser?.username?.substring(1)} + + {loginUser?.username?.substring(1)} + {loginUser.username} @@ -93,13 +112,14 @@ function MobileApp() { margin: 0, minHeight: 200, background: colorBgContainer, - }}> + }} + > {/*
桂林海纳国际旅行社有限公司
*/} - ); + ) } -export default MobileApp; +export default MobileApp diff --git a/src/views/PageSpy.jsx b/src/views/PageSpy.jsx deleted file mode 100644 index 14ad86f..0000000 --- a/src/views/PageSpy.jsx +++ /dev/null @@ -1,17 +0,0 @@ -const PageSpyLog = () => { - return ( - <> - {window.$pageSpy && ( -
{ - window.$pageSpy.triggerPlugins('onOfflineLog', 'download'); - window.$pageSpy.triggerPlugins('onOfflineLog', 'upload'); - }}> - 上传Debug日志 ({window.$pageSpy.address.substring(0, 4)}) - - )} - - ); -}; -export default PageSpyLog;