手动同步改为异步任务并前端轮询状态
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import {
|
||||
BarChart3,
|
||||
TrendingUp,
|
||||
@@ -24,6 +24,7 @@ export function StockOverview({ role }: StockOverviewProps) {
|
||||
const [loading, setLoading] = useState(true)
|
||||
const [syncing, setSyncing] = useState(false)
|
||||
const [error, setError] = useState('')
|
||||
const pollRef = useRef<number | null>(null)
|
||||
|
||||
const canSync = canManageUsers(role)
|
||||
|
||||
@@ -43,20 +44,52 @@ export function StockOverview({ role }: StockOverviewProps) {
|
||||
|
||||
useEffect(() => {
|
||||
fetchAll()
|
||||
return () => {
|
||||
if (pollRef.current) {
|
||||
window.clearInterval(pollRef.current)
|
||||
}
|
||||
}
|
||||
}, [])
|
||||
|
||||
const startPolling = () => {
|
||||
if (pollRef.current) {
|
||||
window.clearInterval(pollRef.current)
|
||||
}
|
||||
pollRef.current = window.setInterval(async () => {
|
||||
try {
|
||||
const j = await api.stockSyncStatus()
|
||||
setJob(j)
|
||||
if (!j || j.status !== 'running') {
|
||||
if (pollRef.current) {
|
||||
window.clearInterval(pollRef.current)
|
||||
pollRef.current = null
|
||||
}
|
||||
setSyncing(false)
|
||||
await fetchAll()
|
||||
if (j?.status === 'failed') {
|
||||
setError(j.error_message || '同步失败')
|
||||
}
|
||||
}
|
||||
} catch (err: any) {
|
||||
if (pollRef.current) {
|
||||
window.clearInterval(pollRef.current)
|
||||
pollRef.current = null
|
||||
}
|
||||
setSyncing(false)
|
||||
setError(err?.message || '轮询同步状态失败')
|
||||
}
|
||||
}, 2000)
|
||||
}
|
||||
|
||||
const handleSync = async () => {
|
||||
setSyncing(true)
|
||||
setError('')
|
||||
try {
|
||||
const res = await api.triggerStockSync()
|
||||
await fetchAll()
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('synced', res.records_count, 'records')
|
||||
await api.triggerStockSync()
|
||||
startPolling()
|
||||
} catch (err: any) {
|
||||
setError(err?.message || '同步失败')
|
||||
} finally {
|
||||
setSyncing(false)
|
||||
setError(err?.message || '同步失败')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ export interface SyncJob {
|
||||
records_count: number
|
||||
started_at: string
|
||||
finished_at?: string
|
||||
error_message: string
|
||||
error_message?: string
|
||||
trigger_by: string
|
||||
}
|
||||
|
||||
@@ -147,5 +147,5 @@ export const api = {
|
||||
stockSyncStatus: () => request<SyncJob | null>('/api/stocks/sync/status'),
|
||||
|
||||
triggerStockSync: () =>
|
||||
request<{ records_count: number }>('/api/admin/stocks/sync', { method: 'POST' }),
|
||||
request<{ job: SyncJob }>('/api/admin/stocks/sync', { method: 'POST' }),
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user