feat: add new file

This commit is contained in:
Daniel
2026-03-01 19:23:48 +08:00
parent d705fd6c83
commit c07fc681dd
24 changed files with 2711 additions and 166 deletions

View File

@@ -1,13 +1,16 @@
import { create } from 'zustand'
import type { MilitarySituation } from '@/data/mockData'
import { INITIAL_MOCK_DATA } from '@/data/mockData'
import { fetchSituation } from '@/api/situation'
import { connectSituationWebSocket } from '@/api/websocket'
interface SituationState {
situation: MilitarySituation
isConnected: boolean
lastError: string | null
isLoading: boolean
setSituation: (situation: MilitarySituation) => void
updateFromWebSocket: (partial: Partial<MilitarySituation>) => void
fetchAndSetSituation: () => Promise<void>
setConnected: (connected: boolean) => void
setLastError: (error: string | null) => void
}
@@ -16,67 +19,48 @@ export const useSituationStore = create<SituationState>((set) => ({
situation: INITIAL_MOCK_DATA,
isConnected: false,
lastError: null,
isLoading: false,
setSituation: (situation) => set({ situation }),
updateFromWebSocket: (partial) =>
set((state) => ({
situation: {
...state.situation,
...partial,
lastUpdated: new Date().toISOString(),
},
})),
fetchAndSetSituation: async () => {
set({ isLoading: true, lastError: null })
try {
const situation = await fetchSituation()
set({ situation })
} catch (err) {
set({
lastError: err instanceof Error ? err.message : 'Failed to fetch situation',
})
} finally {
set({ isLoading: false })
}
},
setConnected: (isConnected) => set({ isConnected }),
setLastError: (lastError) => set({ lastError }),
}))
// WebSocket mock logic - simulates real-time updates without actual simulation
// In production, replace with actual WebSocket connection
let mockWsInterval: ReturnType<typeof setInterval> | null = null
export function startWebSocketMock(): void {
if (mockWsInterval) return
const store = useSituationStore.getState()
store.setConnected(true)
store.setLastError(null)
mockWsInterval = setInterval(() => {
const { situation } = useSituationStore.getState()
const now = Date.now()
// Simulate minor fluctuations in numbers (display-only, no logic)
const fluctuation = () => Math.floor(Math.random() * 3) - 1
useSituationStore.getState().updateFromWebSocket({
usForces: {
...situation.usForces,
summary: {
...situation.usForces.summary,
totalAssets: Math.max(40, situation.usForces.summary.totalAssets + fluctuation()),
},
},
recentUpdates: [
{
id: `u-${now}`,
timestamp: new Date(now).toISOString(),
category: 'intel',
summary: '例行状态同步 - 各系统正常',
severity: 'low',
},
...situation.recentUpdates.slice(0, 3),
],
})
}, 15000) // Update every 15 seconds
export function fetchAndSetSituation(): Promise<void> {
return useSituationStore.getState().fetchAndSetSituation()
}
export function stopWebSocketMock(): void {
if (mockWsInterval) {
clearInterval(mockWsInterval)
mockWsInterval = null
}
let disconnectWs: (() => void) | null = null
export function startSituationWebSocket(): () => void {
useSituationStore.getState().setConnected(true)
useSituationStore.getState().setLastError(null)
disconnectWs = connectSituationWebSocket((data) => {
useSituationStore.getState().setSituation(data as MilitarySituation)
})
return stopSituationWebSocket
}
export function stopSituationWebSocket(): void {
disconnectWs?.()
disconnectWs = null
useSituationStore.getState().setConnected(false)
}