fix(playback): 增加库位数据支持,优化回放模式下的数据处理逻辑
This commit is contained in:
parent
85f7b94313
commit
1fbdb5efcb
@ -8,7 +8,7 @@ import ws from '../services/ws';
|
||||
|
||||
// Define the structure of WebSocket messages for playback
|
||||
type PlaybackMessage = {
|
||||
type: 'AMR' | 'SCENE';
|
||||
type: 'AMR' | 'SCENE' | 'LOCATION';
|
||||
timestamp: number;
|
||||
data: any;
|
||||
};
|
||||
@ -18,6 +18,7 @@ type PlaybackSceneData = {
|
||||
totalDuration: number;
|
||||
};
|
||||
|
||||
// Hook's return type definition
|
||||
// Hook's return type definition
|
||||
export interface UsePlaybackWebSocketReturn {
|
||||
// Connection status
|
||||
@ -31,6 +32,7 @@ export interface UsePlaybackWebSocketReturn {
|
||||
// Data for rendering
|
||||
currentSceneId: Ref<string | null>;
|
||||
sceneJson: Ref<string | null>;
|
||||
locationData: Ref<any[]>; // 新增:用于存储库位数据
|
||||
|
||||
// Methods
|
||||
connect: (historySceneId: string) => void;
|
||||
@ -50,6 +52,7 @@ export function usePlaybackWebSocket(editorService: ShallowRef<EditorService | u
|
||||
const totalDuration = ref(0);
|
||||
const currentSceneId = ref<string | null>(null);
|
||||
const sceneJson = ref<string | null>(null);
|
||||
const locationData = ref<any[]>([]); // 新增:库位数据的响应式引用
|
||||
|
||||
const { calculateCenterPoint, jumpToPosition } = useViewState();
|
||||
|
||||
@ -100,6 +103,9 @@ export function usePlaybackWebSocket(editorService: ShallowRef<EditorService | u
|
||||
(msg.data as RobotRealtimeInfo[]).forEach((robot) => {
|
||||
latestRobotData.set(robot.id, robot);
|
||||
});
|
||||
} else if (msg.type === 'LOCATION') {
|
||||
// 新增:处理库位数据
|
||||
locationData.value = msg.data;
|
||||
}
|
||||
};
|
||||
|
||||
@ -230,6 +236,7 @@ export function usePlaybackWebSocket(editorService: ShallowRef<EditorService | u
|
||||
totalDuration,
|
||||
currentSceneId,
|
||||
sceneJson,
|
||||
locationData, // 新增
|
||||
connect,
|
||||
disconnect,
|
||||
play,
|
||||
|
||||
@ -112,9 +112,12 @@ const playback = usePlaybackWebSocket(editor);
|
||||
watch(mode, async (newMode) => {
|
||||
if (newMode === 'live') {
|
||||
playback.disconnect();
|
||||
storageLocationService.value?.setPlaybackMode(false);
|
||||
await monitorScene();
|
||||
storageLocationService.value?.startMonitoring({ interval: 1 });
|
||||
} else {
|
||||
client.value?.close();
|
||||
storageLocationService.value?.setPlaybackMode(true);
|
||||
playback.connect(props.sid); // Connect once using props.sid
|
||||
}
|
||||
});
|
||||
@ -127,6 +130,44 @@ watch(playback.sceneJson, async (newJson) => {
|
||||
}
|
||||
});
|
||||
|
||||
watch(playback.locationData, (newData) => {
|
||||
if (newData) {
|
||||
storageLocationService.value?.handlePlaybackData(newData);
|
||||
}
|
||||
});
|
||||
|
||||
let mockLocationInterval: NodeJS.Timeout;
|
||||
onMounted(() => {
|
||||
// 仅在回放模式下启动模拟数据
|
||||
if (isPlaybackMode.value) {
|
||||
let occupied = false;
|
||||
mockLocationInterval = setInterval(() => {
|
||||
const mockData = {
|
||||
type: 'LOCATION',
|
||||
timestamp: playback.currentTime.value,
|
||||
data: [
|
||||
{
|
||||
id: '666',
|
||||
label: '1-1',
|
||||
stationName: 'AP190',
|
||||
occupied: occupied,
|
||||
locked: false,
|
||||
disabled: false,
|
||||
emptyTray: false,
|
||||
},
|
||||
],
|
||||
};
|
||||
// 模拟数据推送
|
||||
storageLocationService.value?.handlePlaybackData(mockData.data);
|
||||
occupied = !occupied; // 切换状态
|
||||
}, 2000); // 每2秒更新一次
|
||||
}
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
clearInterval(mockLocationInterval);
|
||||
});
|
||||
|
||||
watch(selectedDate, (date) => {
|
||||
if (date) {
|
||||
const startOfDayTimestamp = date.startOf('day').valueOf();
|
||||
|
||||
@ -115,6 +115,7 @@ export class StorageLocationService {
|
||||
private config: StorageLocationConfig;
|
||||
// 渲染调度标记,避免在高频事件中重复 render
|
||||
private renderScheduled = false;
|
||||
private isPlaybackMode = false;
|
||||
|
||||
constructor(editor: EditorService, sceneId: string, config?: Partial<StorageLocationConfig>) {
|
||||
this.editor = editor;
|
||||
@ -472,6 +473,9 @@ export class StorageLocationService {
|
||||
* @param options 监控选项
|
||||
*/
|
||||
async startMonitoring(options: { interval?: number } = {}) {
|
||||
if (this.isPlaybackMode) {
|
||||
return;
|
||||
}
|
||||
this.stopMonitoring();
|
||||
|
||||
// 监控库位状态
|
||||
@ -765,6 +769,70 @@ export class StorageLocationService {
|
||||
this.storageLocations.value.clear();
|
||||
this.editor = null;
|
||||
}
|
||||
|
||||
setPlaybackMode(isPlayback: boolean) {
|
||||
this.isPlaybackMode = isPlayback;
|
||||
}
|
||||
|
||||
handlePlaybackData(data: any[]) {
|
||||
const stationToPointIdMap = this.buildStationToPointIdMap();
|
||||
|
||||
const locationsByPointId = new Map<string, StorageLocationInfo[]>();
|
||||
data.forEach((location) => {
|
||||
const pointId = stationToPointIdMap.get(location.stationName);
|
||||
if (pointId) {
|
||||
if (!locationsByPointId.has(pointId)) {
|
||||
locationsByPointId.set(pointId, []);
|
||||
}
|
||||
locationsByPointId.get(pointId)!.push({
|
||||
...location,
|
||||
is_occupied: location.occupied,
|
||||
is_locked: location.locked,
|
||||
is_disabled: location.disabled,
|
||||
is_empty_tray: location.emptyTray,
|
||||
layer_name: location.label,
|
||||
station_name: location.stationName,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const changedPointIds = this.getChangedPointIds(locationsByPointId);
|
||||
if (changedPointIds.size === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.storageLocations.value = locationsByPointId;
|
||||
|
||||
storageStateMap.clear();
|
||||
for (const [pointId, list] of locationsByPointId.entries()) {
|
||||
const inner = new Map<string, StorageState>();
|
||||
list.forEach((loc) => {
|
||||
inner.set(loc.layer_name, {
|
||||
occupied: loc.is_occupied,
|
||||
locked: loc.is_locked,
|
||||
disabled: loc.is_disabled,
|
||||
isEmptyTray: loc.is_empty_tray,
|
||||
});
|
||||
});
|
||||
storageStateMap.set(pointId, inner);
|
||||
}
|
||||
|
||||
this.updatePointBorderColorsOptimized(changedPointIds);
|
||||
|
||||
for (const pointId of changedPointIds) {
|
||||
const pointPen = this.editor?.getPenById(pointId);
|
||||
const storageNames = pointPen?.point?.associatedStorageLocations;
|
||||
if (pointPen && Array.isArray(storageNames) && storageNames.length > 0) {
|
||||
const existing = this.getStorageLocationPens(pointId);
|
||||
if (existing.length > 0) {
|
||||
this.update(pointId, storageNames);
|
||||
} else {
|
||||
this.create(pointId, storageNames);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.scheduleRender();
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== 新增:简化的库位更新API ====================
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user