feat: 迁入 MiGu.Server、平台前端与车辆列表 reflection 回退
从 Simple-FR 拆出 Platform.Server 并重命名为 MiGu.Server;frontends 源码与构建脚本迁入本仓库。地图监控在 projection/cars 失败或为空时回退 reflection 车辆列表;Simple 仓库已移除旧 Platform.Server。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
import { onBeforeUnmount, onMounted } from 'vue'
|
||||
import { useProjectionStream, type StreamEvent } from './useProjectionStream'
|
||||
|
||||
/**
|
||||
* 编辑器 / 监控页对 SimpleLite SSE 的事件订阅封装,把以下 5 类事件转给业务回调:
|
||||
*
|
||||
* - `alarm` (来自 AlarmStreamService):报警新增/更新/解除
|
||||
* - `object-created` (来自 MapEditApiController):对象创建后
|
||||
* - `object-deleted` (来自 MapEditApiController):对象删除后
|
||||
* - `object-patched` (来自 MapEditApiController):对象字段被 patch 后
|
||||
* - `object-batch-changed`(来自 batch / ai 调用):一组对象变化,建议直接整页重拉
|
||||
* - `pick-result` (来自 /pick):拾取会话完成
|
||||
*
|
||||
* 业务页只用关心自己感兴趣的事件回调,其它走默认忽略。
|
||||
*/
|
||||
|
||||
export interface AlarmEvent {
|
||||
action: 'raise' | 'update' | 'clear'
|
||||
carId: number
|
||||
carName: string
|
||||
info?: string
|
||||
x?: number
|
||||
y?: number
|
||||
timestamp: string
|
||||
}
|
||||
|
||||
export interface ObjectChangeEvent {
|
||||
kind: string
|
||||
id: number
|
||||
typeName?: string
|
||||
source?: string
|
||||
}
|
||||
|
||||
export interface PickResultEvent {
|
||||
x: number
|
||||
y: number
|
||||
siteId: number
|
||||
}
|
||||
|
||||
export interface SelectionDetailEvent {
|
||||
/** 主选中 kind (site|track|car|null);当多选时取首个非空集合的 kind。 */
|
||||
kind: 'site' | 'track' | 'car' | null
|
||||
/** 主选中 id;多选时取首个。 */
|
||||
id: number
|
||||
siteIds: number[]
|
||||
trackIds: number[]
|
||||
carIds: number[]
|
||||
/** 完整对象名列表,例如 ["UISite-12", "UITrack-7", "Car-3"]。 */
|
||||
names: string[]
|
||||
}
|
||||
|
||||
export interface MapEditStreamHandlers {
|
||||
onAlarm?: (e: AlarmEvent) => void
|
||||
onObjectCreated?: (e: ObjectChangeEvent) => void
|
||||
onObjectDeleted?: (e: ObjectChangeEvent) => void
|
||||
onObjectPatched?: (e: ObjectChangeEvent) => void
|
||||
onObjectBatchChanged?: (e: { count: number; source?: string }) => void
|
||||
onPickResult?: (e: PickResultEvent) => void
|
||||
onSelectionDetail?: (e: SelectionDetailEvent) => void
|
||||
}
|
||||
|
||||
export function useMapEditStream(handlers: MapEditStreamHandlers) {
|
||||
const stream = useProjectionStream({ autoConnect: false })
|
||||
|
||||
function dispatch(ev: StreamEvent) {
|
||||
const payload = ev?.payload as Record<string, unknown> | undefined
|
||||
if (!payload) return
|
||||
switch (ev.kind) {
|
||||
case 'alarm':
|
||||
handlers.onAlarm?.(payload as unknown as AlarmEvent)
|
||||
break
|
||||
case 'object-created':
|
||||
handlers.onObjectCreated?.(payload as unknown as ObjectChangeEvent)
|
||||
break
|
||||
case 'object-deleted':
|
||||
handlers.onObjectDeleted?.(payload as unknown as ObjectChangeEvent)
|
||||
break
|
||||
case 'object-patched':
|
||||
handlers.onObjectPatched?.(payload as unknown as ObjectChangeEvent)
|
||||
break
|
||||
case 'object-batch-changed':
|
||||
handlers.onObjectBatchChanged?.(payload as unknown as { count: number; source?: string })
|
||||
break
|
||||
case 'pick-result':
|
||||
handlers.onPickResult?.(payload as unknown as PickResultEvent)
|
||||
break
|
||||
case 'selection-detail':
|
||||
handlers.onSelectionDetail?.(payload as unknown as SelectionDetailEvent)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
stream.on(dispatch)
|
||||
stream.connect()
|
||||
})
|
||||
onBeforeUnmount(() => {
|
||||
stream.off(dispatch)
|
||||
stream.disconnect()
|
||||
})
|
||||
|
||||
return { connected: stream.connected }
|
||||
}
|
||||
Reference in New Issue
Block a user