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/AuthApp.jsx

201 lines
6.6 KiB
JavaScript

import ErrorBoundary from '@/components/ErrorBoundary'
import useAuthStore from '@/stores/AuthStore'
import { useThemeContext } from '@/stores/ThemeContext'
import useConversationStore from '@/stores/ConversationStore'
import {
App as AntApp,
ConfigProvider,
Empty,
Modal,
message,
FloatButton,
theme,
} from 'antd'
import { AudioOutlined, AudioTwoTone, BugOutlined, CustomerServiceOutlined } from '@ant-design/icons'
import zhLocale from 'antd/locale/zh_CN'
import 'dayjs/locale/zh-cn'
import { useEffect } from 'react'
import { Link, NavLink, Outlet, useHref, useNavigate } from 'react-router-dom'
import { appendRequestHeader } from '@/utils/request'
import { loadPageSpy } from '@/utils/pagespy'
import AppLogo from '@/assets/highlights_travel_300_300.png'
import '@/assets/App.css'
import 'react-chat-elements/dist/main.css'
import EmailFetch from './Conversations/Online/Components/EmailFetch'
import FetchEmailWorker from './../workers/fetchEmailWorker?worker&url'
import { readWebsocketLog } from '@/utils/indexedDB'
import { useGlobalNotify } from '@/hooks/useGlobalNotify'
import GeneratePaymentDrawer from './Conversations/Online/Components/GeneratePaymentDrawer'
import GenerateAutoDocDrawer from './Conversations/Online/Components/GenerateAutoDocDrawer'
// const fetchEmailWorkerURL = new URL('/src/workers/fetchEmailWorker.js', import.meta.url);
const fetchEmailWorker = new Worker(FetchEmailWorker, { type: 'module' });
function AuthApp() {
const navigate = useNavigate()
const [messageApi, contextHolder] = message.useMessage()
const { colorPrimary, borderRadius } = useThemeContext()
const [loginUser, sendNotify] = useAuthStore((state) => [
state.loginUser, state.sendNotify
])
const href = useHref()
const [connectWebsocket, fetchInitialData, disconnectWebsocket] =
useConversationStore((state) => [
state.connectWebsocket,
state.fetchInitialData,
state.disconnectWebsocket,
])
useEffect(() => {
if (!('Notification' in window)) {
// alert("This browser does not support desktop notification");
} else {
Notification.requestPermission()
}
let _fetchEmailWorker;
if (loginUser.userId > 0) {
appendRequestHeader('X-User-Id', loginUser.userId)
loadPageSpy(loginUser.username)
connectWebsocket(loginUser.userId)
fetchInitialData(loginUser)
_fetchEmailWorker = startEmailInterval(loginUser.userId)
}
return () => {
disconnectWebsocket()
fetchEmailWorker.postMessage({ command: 'logout' })
if (_fetchEmailWorker) {
_fetchEmailWorker.terminate();
}
}
}, [])
useGlobalNotify();
const startEmailInterval = (userId) => {
// const fetchEmailWorker = new Worker(fetchEmailWorkerURL, { type: 'module' });
fetchEmailWorker.onerror = function(error) {
console.error('There was an error in the worker', error);
};
fetchEmailWorker.onmessage = function(event) {
// console.log('Received message from worker', event.data, event.message);
};
fetchEmailWorker.postMessage({ command: 'fetchEmail', param: { opi_sn: userId } });
return fetchEmailWorker;
}
const uploadLog = async () => {
await readWebsocketLog()
if (window.$pageSpy) {
// window.$pageSpy.triggerPlugins('onOfflineLog', 'upload')
try {
// await window.$harbor.upload() // 上传日志 { clearCache: true, remark: '' }
// 上传最近 1 小时的日志, 直接upload 所有日志: 413 Payload Too Large
const now = Date.now()
await window.$harbor.uploadPeriods({
startTime: now - 60 * 60000,
endTime: now,
})
messageApi.info('Success')
// clearWebsocketLog()
sendNotify()
} catch (error) {
messageApi.error('Failure')
}
} else {
messageApi.error('Failure')
}
}
// 除了路由 /p...以外都需要登陆系统
const needToLogin = loginUser.userId === -1 && href.indexOf('/p/') === -1
const isMobileApp =
navigator.userAgent.match(
/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i,
) !== null
const floatButtonLineEnd = isMobileApp ? 0 : 24
const floatTrigger = isMobileApp ? 'click' : null
useEffect(() => {
if (needToLogin) {
navigate('/p/dingding/login?origin_url=' + href)
}
// 销毁弹出的确认窗。处理路由前进、后退不能销毁确认对话框的问题
Modal.destroyAll()
}, [href])
return (
<ConfigProvider
theme={{
token: {
colorPrimary: colorPrimary,
borderRadius: borderRadius,
fontFamily:
"-apple-system,BlinkMacSystemFont,Roboto,'Helvetica Neue',Arial,'Noto Sans',sans-serif,'Noto Color Emoji','Apple Color Emoji'",
},
algorithm: theme.defaultAlgorithm,
}}
locale={zhLocale}
renderEmpty={() => <Empty description={false} />}
>
<AntApp>
<ErrorBoundary>
<FloatButton.Group
shape='square'
placement={'left'}
trigger={floatTrigger}
style={{
insetInlineEnd: floatButtonLineEnd,
insetBlockEnd: floatButtonLineEnd,
flexDirection: 'row',
}}
icon={<CustomerServiceOutlined />}
>
<EmailFetch />
<FloatButton icon={<BugOutlined />} tooltip={<div>上传日志给研发部</div>} onClick={() => uploadLog()} />
<FloatButton.BackTop />
</FloatButton.Group>
{contextHolder}
{needToLogin ? <>login...</> : <Outlet />}
<dialog id="about-dialog" className="border-0">
<img className="logo" src={AppLogo} alt="logo" />
<section className="about">
<h1>销售平台</h1>
<h2>Sales CRM</h2>
<p>Haina travel global sales CRM system</p>
</section>
<form className="actions flex gap-1" method="dialog">
<button
value="cancel"
className="px-4 py-2 rounded-full border-0"
>
Close
</button>
<button
value="install"
id="install-button"
className="px-4 py-2 rounded-full border-0 border-transparent bg-indigo-500 text-white"
>
Install app
</button>
</form>
</dialog>
<GeneratePaymentDrawer />
<GenerateAutoDocDrawer />
</ErrorBoundary>
</AntApp>
</ConfigProvider>
)
}
export default AuthApp