|
|
|
@ -623,6 +623,8 @@ export default { |
|
|
|
plans: [], |
|
|
|
activeRightTab: 'plan', |
|
|
|
activeRouteIds: [], // 存储当前所有选中的航线ID |
|
|
|
/** 新加入时收到的房间可见航线 ID,若 routes 未加载则暂存,getList 完成后应用 */ |
|
|
|
roomStatePendingVisibleRouteIds: [], |
|
|
|
/** 航线上锁状态:routeId -> true 上锁,与地图右键及右侧列表锁图标同步 */ |
|
|
|
routeLocked: {}, |
|
|
|
// 冲突数据(由 runConflictCheck 根据当前航线与时间轴计算真实问题) |
|
|
|
@ -1417,6 +1419,9 @@ export default { |
|
|
|
if (this.isMySyncSession(senderSessionId)) return; |
|
|
|
this.applySyncPlatformStyles(); |
|
|
|
}, |
|
|
|
onRoomState: (visibleRouteIds) => { |
|
|
|
this.applyRoomStateVisibleRoutes(visibleRouteIds); |
|
|
|
}, |
|
|
|
onConnected: () => {}, |
|
|
|
onDisconnected: () => { |
|
|
|
this.onlineCount = 0; |
|
|
|
@ -1436,12 +1441,31 @@ export default { |
|
|
|
this.wsConnection.disconnect(); |
|
|
|
this.wsConnection = null; |
|
|
|
} |
|
|
|
this.roomStatePendingVisibleRouteIds = []; |
|
|
|
this.wsOnlineMembers = []; |
|
|
|
this.mySyncSessionIds = []; |
|
|
|
this.onlineCount = 0; |
|
|
|
this.chatMessages = []; |
|
|
|
this.privateChatMessages = {}; |
|
|
|
}, |
|
|
|
/** 应用房间状态中的可见航线(新加入用户同步;若 routes 未加载则暂存) */ |
|
|
|
async applyRoomStateVisibleRoutes(visibleRouteIds) { |
|
|
|
if (!visibleRouteIds || !Array.isArray(visibleRouteIds) || visibleRouteIds.length === 0) return; |
|
|
|
if (!this.routes || this.routes.length === 0) { |
|
|
|
this.roomStatePendingVisibleRouteIds = visibleRouteIds; |
|
|
|
return; |
|
|
|
} |
|
|
|
for (const routeId of visibleRouteIds) { |
|
|
|
await this.applySyncRouteVisibility(routeId, true); |
|
|
|
} |
|
|
|
}, |
|
|
|
/** 应用暂存的房间可见航线(getList 完成后调用) */ |
|
|
|
async applyRoomStatePending() { |
|
|
|
if (this.roomStatePendingVisibleRouteIds.length === 0) return; |
|
|
|
const pending = [...this.roomStatePendingVisibleRouteIds]; |
|
|
|
this.roomStatePendingVisibleRouteIds = []; |
|
|
|
await this.applyRoomStateVisibleRoutes(pending); |
|
|
|
}, |
|
|
|
/** 判断是否为当前连接发出的同步消息(避免自己发的消息再应用一次) */ |
|
|
|
isMySyncSession(senderSessionId) { |
|
|
|
if (!senderSessionId) return false; |
|
|
|
@ -1920,6 +1944,7 @@ export default { |
|
|
|
}).catch(() => {}); |
|
|
|
} |
|
|
|
} |
|
|
|
this.$nextTick(() => this.applyRoomStatePending()); |
|
|
|
} |
|
|
|
} catch (error) { |
|
|
|
console.error("数据加载失败:", error); |
|
|
|
@ -3613,25 +3638,72 @@ export default { |
|
|
|
const minutes = absMin % 60; |
|
|
|
return `K${sign}${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}:00`; |
|
|
|
}, |
|
|
|
selectPlan(plan) { |
|
|
|
async selectPlan(plan) { |
|
|
|
if (plan && plan.id) { |
|
|
|
this.selectedPlanId = plan.id; |
|
|
|
this.selectedPlanDetails = plan; |
|
|
|
} else { |
|
|
|
this.selectedPlanId = null; |
|
|
|
this.selectedPlanDetails = null; |
|
|
|
this.selectedRouteId = null; |
|
|
|
this.selectedRouteDetails = null; |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
// 重置状态 |
|
|
|
this.selectedRouteId = null; |
|
|
|
this.selectedRouteDetails = null; |
|
|
|
this.activeRouteIds = []; |
|
|
|
// 清空地图上的航点/航线及探测区、威力区(按 routeId 逐个移除,避免误删其他实体) |
|
|
|
if (this.$refs.cesiumMap) { |
|
|
|
[...this.activeRouteIds].forEach(routeId => { |
|
|
|
this.$refs.cesiumMap.removeRouteById(routeId); |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
// 物理清场(仅航点/航线;空域图形与房间绑定,不随方案切换) |
|
|
|
if (this.$refs.cesiumMap && this.$refs.cesiumMap.clearAllWaypoints) { |
|
|
|
this.$refs.cesiumMap.clearAllWaypoints(); |
|
|
|
// 保留 activeRouteIds,恢复显示该方案下已打开的航线(含联网同步的) |
|
|
|
const planRouteIds = this.activeRouteIds.filter(id => { |
|
|
|
const r = this.routes.find(x => x.id === id); |
|
|
|
return r && r.scenarioId === plan.id; |
|
|
|
}); |
|
|
|
if (planRouteIds.length > 0) { |
|
|
|
for (const routeId of planRouteIds) { |
|
|
|
const route = this.routes.find(r => r.id === routeId); |
|
|
|
if (!route) continue; |
|
|
|
try { |
|
|
|
const res = await getRoutes(route.id); |
|
|
|
if (res.code !== 200 || !res.data) continue; |
|
|
|
const waypoints = res.data.waypoints || []; |
|
|
|
const routeIndex = this.routes.findIndex(r => r.id === route.id); |
|
|
|
if (routeIndex > -1) { |
|
|
|
this.$set(this.routes, routeIndex, { ...this.routes[routeIndex], waypoints }); |
|
|
|
} |
|
|
|
if (waypoints.length > 0 && this.$refs.cesiumMap) { |
|
|
|
const roomId = this.currentRoomId; |
|
|
|
if (roomId && route.platformId) { |
|
|
|
try { |
|
|
|
const styleRes = await getPlatformStyle({ roomId, routeId: route.id, platformId: route.platformId }); |
|
|
|
if (styleRes.data) this.$refs.cesiumMap.setPlatformStyle(route.id, styleRes.data); |
|
|
|
} catch (_) {} |
|
|
|
} |
|
|
|
this.$refs.cesiumMap.renderRouteWaypoints(waypoints, route.id, route.platformId, route.platform, this.parseRouteStyle(route.attributes)); |
|
|
|
} |
|
|
|
} catch (_) {} |
|
|
|
} |
|
|
|
const firstId = planRouteIds[0]; |
|
|
|
const firstRoute = this.routes.find(r => r.id === firstId); |
|
|
|
if (firstRoute && firstRoute.waypoints) { |
|
|
|
this.selectedRouteId = firstRoute.id; |
|
|
|
this.selectedRouteDetails = { |
|
|
|
id: firstRoute.id, |
|
|
|
name: firstRoute.callSign || firstRoute.name, |
|
|
|
waypoints: firstRoute.waypoints, |
|
|
|
platformId: firstRoute.platformId, |
|
|
|
platform: firstRoute.platform, |
|
|
|
attributes: firstRoute.attributes |
|
|
|
}; |
|
|
|
} |
|
|
|
} else { |
|
|
|
this.selectedRouteId = null; |
|
|
|
this.selectedRouteDetails = null; |
|
|
|
} |
|
|
|
console.log(`>>> [切换成功] 已进入方案: ${plan && plan.name},地图已清空,列表已展开。`); |
|
|
|
console.log(`>>> [切换成功] 已进入方案: ${plan.name},已恢复显示 ${planRouteIds.length} 条航线。`); |
|
|
|
}, |
|
|
|
/** 切换航线:实现多选/开关逻辑 */ |
|
|
|
async selectRoute(route) { |
|
|
|
|