增加订单实时状态同步
This commit is contained in:
@@ -44,10 +44,12 @@ import {
|
||||
import {
|
||||
clearAdminSession,
|
||||
getAdminRole,
|
||||
getAdminToken,
|
||||
getAdminTokenExpiresAt,
|
||||
getAdminUsername,
|
||||
} from '@/utils/admin-auth'
|
||||
import { formatAdminDateTime } from '@/utils/admin-time'
|
||||
import { useRealtimeEvents, type RealtimeEvent } from '@/hooks/useRealtimeEvents'
|
||||
|
||||
const SIDEBAR_COLLAPSED_KEY = 'react-admin-sidebar-collapsed'
|
||||
const NOTIFICATION_SOUND_KEY = 'admin-notification-sound-enabled'
|
||||
@@ -88,6 +90,15 @@ export default function AdminLayout() {
|
||||
const notifications = notificationsQuery.data?.data.items || []
|
||||
const pendingNotificationCount = Number(notificationsQuery.data?.data.pendingCount || 0)
|
||||
|
||||
useRealtimeEvents({
|
||||
url: '/api/v1/admin/realtime',
|
||||
token: getAdminToken(),
|
||||
onEvent: (event) => handleAdminRealtimeEvent(event, queryClient),
|
||||
onConnected: () => {
|
||||
void invalidateAdminRealtimeQueries(queryClient)
|
||||
},
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
const currentVersions = new Map(
|
||||
notifications.map((notification) => [notification.notificationId, notification.updatedAt]),
|
||||
@@ -343,6 +354,40 @@ export default function AdminLayout() {
|
||||
)
|
||||
}
|
||||
|
||||
function handleAdminRealtimeEvent(
|
||||
event: RealtimeEvent,
|
||||
queryClient: ReturnType<typeof useQueryClient>,
|
||||
) {
|
||||
if (event.type === 'admin_notification.changed') {
|
||||
void queryClient.invalidateQueries({ queryKey: ['admin-notifications'] })
|
||||
}
|
||||
if (event.type === 'order.changed') {
|
||||
void queryClient.invalidateQueries({ queryKey: ['admin-orders'] })
|
||||
void queryClient.invalidateQueries({ queryKey: ['admin-order-detail', String(event.entityId)] })
|
||||
void queryClient.invalidateQueries({ queryKey: ['admin-tasks'] })
|
||||
void queryClient.invalidateQueries({ queryKey: ['admin-dashboard-summary'] })
|
||||
}
|
||||
if (event.type === 'work_order.changed') {
|
||||
void queryClient.invalidateQueries({ queryKey: ['admin-worker-platform-orders'] })
|
||||
void queryClient.invalidateQueries({ queryKey: ['admin-worker-platform-summary'] })
|
||||
}
|
||||
if (event.type === 'worker_finance_request.changed') {
|
||||
void queryClient.invalidateQueries({ queryKey: ['admin-worker-platform-finance-requests'] })
|
||||
}
|
||||
}
|
||||
|
||||
function invalidateAdminRealtimeQueries(queryClient: ReturnType<typeof useQueryClient>) {
|
||||
return Promise.all([
|
||||
queryClient.invalidateQueries({ queryKey: ['admin-notifications'] }),
|
||||
queryClient.invalidateQueries({ queryKey: ['admin-orders'] }),
|
||||
queryClient.invalidateQueries({ queryKey: ['admin-tasks'] }),
|
||||
queryClient.invalidateQueries({ queryKey: ['admin-dashboard-summary'] }),
|
||||
queryClient.invalidateQueries({ queryKey: ['admin-worker-platform-orders'] }),
|
||||
queryClient.invalidateQueries({ queryKey: ['admin-worker-platform-finance-requests'] }),
|
||||
queryClient.invalidateQueries({ queryKey: ['admin-worker-platform-summary'] }),
|
||||
])
|
||||
}
|
||||
|
||||
type NotificationAlertKind =
|
||||
| 'withdraw'
|
||||
| 'recharge'
|
||||
|
||||
@@ -5,12 +5,15 @@ import {
|
||||
UserOutlined,
|
||||
} from '@ant-design/icons'
|
||||
import { App, Button, Layout, Menu, Typography } from 'antd'
|
||||
import { useQueryClient } from '@tanstack/react-query'
|
||||
import type { MenuProps } from 'antd'
|
||||
import { Outlet, useLocation, useNavigate } from 'react-router'
|
||||
|
||||
import { logoutWorker } from '@/services/worker'
|
||||
import { useIsMobile } from '@/utils/use-is-mobile'
|
||||
import { clearWorkerSession, getWorkerStatus, getWorkerUsername } from '@/utils/worker-auth'
|
||||
import { getWorkerToken } from '@/utils/worker-auth'
|
||||
import { useRealtimeEvents, type RealtimeEvent } from '@/hooks/useRealtimeEvents'
|
||||
|
||||
const menuItems: MenuProps['items'] = [
|
||||
{ key: '/hall', icon: <ShoppingOutlined />, label: '抢单大厅' },
|
||||
@@ -31,8 +34,18 @@ export default function WorkerLayout() {
|
||||
const { message, modal } = App.useApp()
|
||||
const username = getWorkerUsername() || '打手'
|
||||
const status = getWorkerStatus()
|
||||
const queryClient = useQueryClient()
|
||||
const currentKey = resolveSelectedKey(location.pathname)
|
||||
|
||||
useRealtimeEvents({
|
||||
url: '/api/v1/worker/realtime',
|
||||
token: getWorkerToken(),
|
||||
onEvent: (event) => handleWorkerRealtimeEvent(event, queryClient),
|
||||
onConnected: () => {
|
||||
void invalidateWorkerRealtimeQueries(queryClient)
|
||||
},
|
||||
})
|
||||
|
||||
async function submitLogout() {
|
||||
try {
|
||||
await logoutWorker()
|
||||
@@ -143,6 +156,42 @@ export default function WorkerLayout() {
|
||||
)
|
||||
}
|
||||
|
||||
function handleWorkerRealtimeEvent(
|
||||
event: RealtimeEvent,
|
||||
queryClient: ReturnType<typeof useQueryClient>,
|
||||
) {
|
||||
if (event.type === 'work_order.changed') {
|
||||
if (event.scopes.includes('worker_hall')) {
|
||||
void queryClient.invalidateQueries({ queryKey: ['worker-hall-orders'] })
|
||||
void queryClient.invalidateQueries({ queryKey: ['worker-hall-summary'] })
|
||||
}
|
||||
if (event.scopes.includes('worker_my_orders')) {
|
||||
void queryClient.invalidateQueries({ queryKey: ['worker-my-orders'] })
|
||||
void queryClient.invalidateQueries({ queryKey: ['worker-my-orders-overview'] })
|
||||
}
|
||||
}
|
||||
if (event.type === 'worker_finance_request.changed') {
|
||||
void queryClient.invalidateQueries({ queryKey: ['worker-finance-requests'] })
|
||||
void queryClient.invalidateQueries({ queryKey: ['worker-profile'] })
|
||||
}
|
||||
if (event.type === 'worker_wallet.changed') {
|
||||
void queryClient.invalidateQueries({ queryKey: ['worker-wallet-ledgers'] })
|
||||
void queryClient.invalidateQueries({ queryKey: ['worker-profile'] })
|
||||
}
|
||||
}
|
||||
|
||||
function invalidateWorkerRealtimeQueries(queryClient: ReturnType<typeof useQueryClient>) {
|
||||
return Promise.all([
|
||||
queryClient.invalidateQueries({ queryKey: ['worker-hall-orders'] }),
|
||||
queryClient.invalidateQueries({ queryKey: ['worker-hall-summary'] }),
|
||||
queryClient.invalidateQueries({ queryKey: ['worker-my-orders'] }),
|
||||
queryClient.invalidateQueries({ queryKey: ['worker-my-orders-overview'] }),
|
||||
queryClient.invalidateQueries({ queryKey: ['worker-profile'] }),
|
||||
queryClient.invalidateQueries({ queryKey: ['worker-wallet-ledgers'] }),
|
||||
queryClient.invalidateQueries({ queryKey: ['worker-finance-requests'] }),
|
||||
])
|
||||
}
|
||||
|
||||
function resolveSelectedKey(pathname: string) {
|
||||
if (pathname.startsWith('/orders')) return '/orders'
|
||||
if (pathname.startsWith('/profile')) return '/profile'
|
||||
|
||||
Reference in New Issue
Block a user