diff --git a/src/main.jsx b/src/main.jsx index 972bfd2..d14fa16 100644 --- a/src/main.jsx +++ b/src/main.jsx @@ -3,8 +3,9 @@ import ReactDOM from 'react-dom/client' import { createBrowserRouter, RouterProvider, useNavigate } from 'react-router-dom' import { ThemeContext } from '@/stores/ThemeContext' import AuthApp from '@/views/AuthApp' -import Standlone from '@/views/Standlone' +import DesktopApp from '@/views/DesktopApp' import MobileApp from '@/views/MobileApp' +import Standlone from '@/views/Standlone' import OrderFollow from '@/views/OrderFollow' import ChatHistory from '@/views/ChatHistory' import SalesManagement from '@/views/SalesManagement' @@ -27,13 +28,26 @@ const router = createBrowserRouter([ element: , errorElement: , children: [ - { index: true, element: }, - { path: 'order/follow', element: }, - { path: 'chat/history', element: }, - { path: 'sales/management', element: }, - { path: 'order/chat/:order_sn', element: }, - { path: 'order/chat', element: }, - { path: 'account/profile', element: }, + { + element: , + children: [ + { index: true, element: }, + { path: 'order/follow', element: }, + { path: 'chat/history', element: }, + { path: 'sales/management', element: }, + { path: 'order/chat/:order_sn', element: }, + { path: 'order/chat', element: }, + { path: 'account/profile', element: }, + ] + }, + { + path: 'm', + element: , + children: [ + { path: 'conversation', element: }, + { path: 'chat', element: }, + ] + }, ], }, { @@ -45,14 +59,6 @@ const router = createBrowserRouter([ { path: 'mobile-login', element: }, ], }, - { - path: '/m', - element: , - children: [ - { path: 'conversation', element: }, - { path: 'chat', element: }, - ], - }, ]) ReactDOM.createRoot(document.getElementById('root')).render( diff --git a/src/stores/AuthStore.js b/src/stores/AuthStore.js index 87fc537..84fcdb3 100644 --- a/src/stores/AuthStore.js +++ b/src/stores/AuthStore.js @@ -1,11 +1,9 @@ import { create } from 'zustand' import { fetchJSON } from '@/utils/request' -import { isNotEmpty } from '@/utils/commons' +import { isEmpty, isNotEmpty } from '@/utils/commons' const useAuthStore = create((set, get) => ({ - // GLOBAL_SALES_LOGIN_USER - // {"userId":"383","userIdStr":"383,609","username":"廖一军","avatarUrl":"https://api.dicebear.com/7.x/miniavs/svg?seed=1","mobile":"+86-18777396951","email":"lyj@hainatravel.com","openId":"iioljiPmZ4RPoOYpkFiSn7IKAiEiE","accountList":[{"OPI_SN":383,"OPI_Code":"LYJ","OPI_NameCN":"廖一军","OPI_DEI_SN":7,"OPI_NameEN":"Jimmy Liow"},{"OPI_SN":609,"OPI_Code":"LYJAH","OPI_NameCN":"廖一军(ah)","OPI_DEI_SN":28,"OPI_NameEN":"Jimmy Liow"}]} loginUser: { userId: -1, userIdStr: '-1', @@ -77,7 +75,12 @@ const useAuthStore = create((set, get) => ({ }, loadUserSession: () => { - const sessionData = window.sessionStorage.getItem('GLOBAL_SALES_LOGIN_USER') + let sessionData = window.sessionStorage.getItem('GLOBAL_SALES_LOGIN_USER') + + if (import.meta.env.DEV && isEmpty(sessionData)) { + sessionData = window.localStorage.getItem('GLOBAL_SALES_LOGIN_USER') + } + if (sessionData !== null) { set(() => ({ loginUser: JSON.parse(sessionData) diff --git a/src/views/AuthApp.jsx b/src/views/AuthApp.jsx index d6b3302..3e60c2b 100644 --- a/src/views/AuthApp.jsx +++ b/src/views/AuthApp.jsx @@ -2,20 +2,15 @@ import ErrorBoundary from '@/components/ErrorBoundary' import useAuthStore from '@/stores/AuthStore' import useConversationStore from '@/stores/ConversationStore' import { useThemeContext } from '@/stores/ThemeContext' -import { DownOutlined } from '@ant-design/icons' -import { App as AntApp, Avatar, Col, ConfigProvider, Dropdown, Empty, Layout, Menu, Row, Space, Typography, theme, Badge } from 'antd' +import { App as AntApp, ConfigProvider, Empty, Layout, Typography, theme } from 'antd' import zhLocale from 'antd/locale/zh_CN' import 'dayjs/locale/zh-cn' import { useEffect, useState } from 'react' -import { Link, NavLink, Outlet, useHref, useNavigate } from 'react-router-dom' +import { 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 AuthApp() { const navigate = useNavigate() @@ -92,76 +87,8 @@ function AuthApp() { renderEmpty={() => } > - - -
- - - - App logo - - - 聊天式销售平台 - - - - 订单跟踪 }, - { key: '/order/chat', label: 在线聊天 - }, - { key: '/chat/history', label: 聊天记录 }, - ]} - /> - - - 个人资料, - key: '1', - }, - { - type: 'divider', - }, - { - label: 退出, - key: '3', - }, - ] - }} - trigger={['click']} - > - e.preventDefault()} style={{ color: colorPrimary }}> - {loginUser?.username?.substring(1)}{loginUser.username} - - - - - -
- - - - - -
桂林海纳国际旅行社有限公司
-
+ +
diff --git a/src/views/Conversations/Components/CustomerProfile.jsx b/src/views/Conversations/Components/CustomerProfile.jsx index 9f59273..7ea7352 100644 --- a/src/views/Conversations/Components/CustomerProfile.jsx +++ b/src/views/Conversations/Components/CustomerProfile.jsx @@ -60,7 +60,8 @@ const CustomerProfile = (() => { { value: 4, label: '等待付订金' }, { value: 5, label: '成行' }, { value: 6, label: '丢失' }, - { value: 7, label: '取消' } + { value: 7, label: '取消' }, + { value: 8, label: '未报价' } ]} /> ]} diff --git a/src/views/DesktopApp.jsx b/src/views/DesktopApp.jsx new file mode 100644 index 0000000..d442f75 --- /dev/null +++ b/src/views/DesktopApp.jsx @@ -0,0 +1,153 @@ +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 ( + +
+ + + + App logo + + + 聊天式销售平台 + + + + 订单跟踪 }, + { key: '/order/chat', label: 在线聊天 + }, + { key: '/chat/history', label: 聊天记录 }, + ]} + /> + + + 个人资料, + key: '1', + }, + { + type: 'divider', + }, + { + label: 退出, + key: '3', + }, + ] + }} + trigger={['click']} + > + e.preventDefault()} style={{ color: colorPrimary }}> + {loginUser?.username?.substring(1)}{loginUser.username} + + + + + +
+ + + + + +
桂林海纳国际旅行社有限公司
+
+ ) +} + +export default DesktopApp diff --git a/src/views/MobileApp.jsx b/src/views/MobileApp.jsx index c00e1d5..bf564ec 100644 --- a/src/views/MobileApp.jsx +++ b/src/views/MobileApp.jsx @@ -2,7 +2,7 @@ import '@/assets/App.css' import AppLogo from '@/assets/logo-gh.png' import { useThemeContext } from '@/stores/ThemeContext' import useAuthStore from '@/stores/AuthStore' -import { App as AntApp, Col, ConfigProvider, Empty, Layout, Row, Typography, theme, Space, Avatar } from 'antd' +import { Col, Layout, Row, Typography, theme, Space, Avatar } from 'antd' import { DownOutlined } from '@ant-design/icons' import { NavLink, Outlet } from 'react-router-dom' const { Header, Footer, Content } = Layout @@ -17,51 +17,32 @@ function MobileApp() { token: { colorBgContainer }, } = theme.useToken() - function renderLayout() { - return ( + return ( + +
+ + + + App logo + + {loginUser?.username?.substring(1)}{loginUser.username} + + +
-
- - - - App logo - - {loginUser?.username?.substring(1)}{loginUser.username} - - -
- - - - - -
桂林海纳国际旅行社有限公司
+ + +
- ) - } - - return ( - } - > - - {renderLayout()} - - +
桂林海纳国际旅行社有限公司
+
) } diff --git a/src/views/OrderFollow.jsx b/src/views/OrderFollow.jsx index e3655ca..018273b 100644 --- a/src/views/OrderFollow.jsx +++ b/src/views/OrderFollow.jsx @@ -367,7 +367,7 @@ function OrderFollow() { disabled={advanceChecked} /> { toggleAdvance(!advanceChecked) }} /> } diff --git a/src/views/mobile/Login.jsx b/src/views/mobile/Login.jsx index 22b9738..1b1caeb 100644 --- a/src/views/mobile/Login.jsx +++ b/src/views/mobile/Login.jsx @@ -1,5 +1,4 @@ -import { memo, useCallback, useEffect, useRef, useState, forwardRef } from 'react' -import { App, Avatar, List, Layout, Input, DatePicker, Flex, Result, Spin } from 'antd' +import { Flex, Result, Spin } from 'antd' function Chat() { @@ -16,7 +15,7 @@ function Chat() { ]} /> - ); + ) } export default Chat