增加订单实时状态同步

This commit is contained in:
yml2213
2026-08-17 14:51:51 +08:00
parent 5330b55b75
commit 18dad9b0fe
13 changed files with 798 additions and 16 deletions
@@ -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'