-1) {
+ // 折叠方案时,取消选中该方案的所有航线
+ this.expandedPlans.splice(index, 1)
+ const planRoutes = this.routes.filter(r => r.scenarioId === planId)
+ planRoutes.forEach(route => {
+ if (this.activeRouteIds.includes(route.id)) {
+ // 触发航线隐藏
+ this.handleToggleRouteVisibility(route)
+ }
+ })
+ // 折叠方案时,取消选中方案
+ this.$emit('select-plan', { id: null })
+ } else {
+ // 展开方案时,选中该方案
+ this.expandedPlans.push(planId)
+ const plan = this.plans.find(p => p.id === planId)
+ if (plan) {
+ this.$emit('select-plan', plan)
+ }
+ // 选中该方案的所有航线
+ const planRoutes = this.routes.filter(r => r.scenarioId === planId)
+ planRoutes.forEach(route => {
+ if (!this.activeRouteIds.includes(route.id)) {
+ this.handleSelectRoute(route)
+ }
+ })
+ }
+ },
+
+ // 切换航线展开/折叠
+ toggleRoute(routeId) {
+ const route = this.routes.find(r => r.id === routeId)
+ if (!route) return
+
+ const isRouteSelected = this.activeRouteIds.includes(routeId)
+ const isRouteExpanded = this.expandedRoutes.includes(routeId)
+
+ if (isRouteSelected) {
+ // 航线已选中
+ if (isRouteExpanded) {
+ // 航线已展开,点击则收回航点
+ const index = this.expandedRoutes.indexOf(routeId)
+ this.expandedRoutes.splice(index, 1)
+ } else {
+ // 航线未展开,点击则展开航点
+ this.expandedRoutes.push(routeId)
+ }
+ } else {
+ // 航线未选中,点击则选中并显示航线和航点
+ this.handleSelectRoute(route)
+ // 选中后自动展开航点
+ this.$nextTick(() => {
+ if (!this.expandedRoutes.includes(routeId)) {
+ this.expandedRoutes.push(routeId)
+ }
+ })
+ }
+ },
+
handleHide() {
this.$emit('hide')
},
@@ -314,6 +364,7 @@ export default {
},
handleSelectRoute(route) {
+ // 确保航线有航点数据
this.$emit('select-route', route)
},
@@ -325,6 +376,14 @@ export default {
this.$emit('create-route')
},
+ handleCreateRouteForPlan(plan) {
+ this.$emit('create-route', plan)
+ },
+
+ handleDeletePlan(plan) {
+ // 暂时留空,后续实现
+ },
+
handleOpenPlanDialog(plan) {
this.$emit('open-plan-dialog', plan)
},
@@ -333,16 +392,27 @@ export default {
this.$emit('open-route-dialog', route)
},
- handleOpenWaypointDialog(point) {
- this.$emit('open-waypoint-dialog', point)
+ handleToggleRouteVisibility(route) {
+ this.$emit('toggle-route-visibility', route)
+ // 当隐藏航线时,自动收回航点列表
+ const routeIndex = this.expandedRoutes.indexOf(route.id)
+ if (routeIndex > -1) {
+ this.expandedRoutes.splice(routeIndex, 1)
+ }
},
- handleAddWaypoint() {
- this.$emit('add-waypoint')
+ getRouteClasses(routeId) {
+ return {
+ active: this.activeRouteIds.includes(routeId)
+ }
},
- handleCancelRoute() {
- this.$emit('cancel-route')
+ handleDeleteRoute(route) {
+ // 暂时留空,后续实现
+ },
+
+ handleOpenWaypointDialog(point) {
+ this.$emit('open-waypoint-dialog', point)
},
handleViewConflict(conflict) {
@@ -466,115 +536,90 @@ export default {
opacity: 0.9;
}
-.route-list {
+.tree-list {
display: flex;
flex-direction: column;
gap: 8px;
}
-.route-item {
+.tree-item {
+ border-radius: 6px;
+ transition: all 0.3s;
+ border: 1px solid rgba(0, 138, 255, 0.1);
+}
+
+.tree-item-header {
display: flex;
align-items: center;
gap: 10px;
padding: 10px;
background: rgba(255, 255, 255, 0.8);
- border-radius: 6px;
cursor: pointer;
transition: all 0.3s;
- border: 1px solid rgba(0, 138, 255, 0.1);
- position: relative;
+ border-radius: 6px;
}
-.route-item:hover {
+.tree-item-header:hover {
background: rgba(0, 138, 255, 0.1);
transform: translateX(-2px);
box-shadow: 0 2px 8px rgba(0, 138, 255, 0.15);
}
-.route-item.active {
- background: rgba(0, 138, 255, 0.15);
- border-color: rgba(0, 138, 255, 0.3);
- box-shadow: 0 2px 10px rgba(0, 138, 255, 0.25);
-}
-
-.route-info {
- flex: 1;
-}
-
-.route-name {
- font-size: 14px;
- font-weight: 500;
- color: #333;
-}
-
-.route-meta {
- font-size: 12px;
- color: #999;
+.tree-item.plan-item .tree-item-header {
+ background: rgba(255, 255, 255, 0.9) !important;
}
-.route-actions {
- display: flex;
- gap: 8px;
+.tree-item.route-item .tree-item-header {
+ background: rgba(255, 255, 255, 0.8) !important;
}
-.route-actions i {
- cursor: pointer;
- color: #008aff;
- font-size: 14px;
- padding: 4px;
- border-radius: 4px;
- transition: all 0.2s;
+.tree-item.route-item:not(.active) .tree-item-header {
+ background: rgba(255, 255, 255, 0.8) !important;
}
-.route-actions i:hover {
- background: rgba(0, 138, 255, 0.1);
- transform: scale(1.2);
+.tree-item.waypoint-item .tree-item-header {
+ background: rgba(224, 238, 255, 0.8);
}
-.waypoint-list {
- display: flex;
- flex-direction: column;
- gap: 8px;
+.tree-item.active .tree-item-header {
+ background: rgba(0, 138, 255, 0.15) !important;
+ border-color: rgba(0, 138, 255, 0.3);
+ box-shadow: 0 2px 10px rgba(0, 138, 255, 0.25);
}
-.waypoint-item {
- display: flex;
- align-items: center;
- gap: 10px;
- padding: 10px;
- background: rgba(255, 255, 255, 0.8);
- border-radius: 6px;
- transition: all 0.3s;
- border: 1px solid rgba(0, 138, 255, 0.1);
+.tree-item.selected .tree-item-header {
+ background: rgba(0, 138, 255, 0.1) !important;
+ border-color: rgba(0, 138, 255, 0.2);
}
-.waypoint-item:hover {
- background: rgba(0, 138, 255, 0.1);
- transform: translateX(-2px);
- box-shadow: 0 2px 8px rgba(0, 138, 255, 0.15);
+.tree-icon {
+ font-size: 16px;
+ color: #008aff;
+ flex-shrink: 0;
}
-.waypoint-info {
+.tree-item-info {
flex: 1;
}
-.waypoint-name {
+.tree-item-name {
font-size: 14px;
font-weight: 500;
color: #333;
}
-.waypoint-meta {
+.tree-item-meta {
font-size: 12px;
color: #999;
}
-.waypoint-actions {
+.tree-item-actions {
display: flex;
gap: 8px;
+ flex-shrink: 0;
}
-.waypoint-actions i {
+.tree-item-actions i {
cursor: pointer;
color: #008aff;
font-size: 14px;
@@ -583,11 +628,27 @@ export default {
transition: all 0.2s;
}
-.waypoint-actions i:hover {
+.tree-item-actions i:hover {
background: rgba(0, 138, 255, 0.1);
transform: scale(1.2);
}
+.tree-children {
+ margin-left: 20px;
+ margin-top: 4px;
+ display: flex;
+ flex-direction: column;
+ gap: 4px;
+}
+
+.route-children {
+ margin-left: 25px;
+}
+
+.waypoint-children {
+ margin-left: 50px;
+}
+
.action-buttons {
display: flex;
gap: 10px;
diff --git a/ruoyi-ui/src/views/childRoom/index.vue b/ruoyi-ui/src/views/childRoom/index.vue
index eaf2c72..72a0ef6 100644
--- a/ruoyi-ui/src/views/childRoom/index.vue
+++ b/ruoyi-ui/src/views/childRoom/index.vue
@@ -106,6 +106,7 @@
({
@@ -1139,56 +1147,92 @@ export default {
const minutes = (val % 4) * 15;
return `K+${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:00`;
},
+
+ createPlan() {
+ this.$message.success('创建方案');
+ },
+
+ openPlanDialog(plan) {
+ this.$message.success('打开方案编辑对话框');
+ },
+
selectPlan(plan) {
- this.selectedPlanId = plan.id;
- this.selectedPlanDetails = 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;
},
- /** 切换航线:实现多选/开关逻辑 */
+ /** 切换航线:实现复杂的交互逻辑 */
async selectRoute(route) {
const index = this.activeRouteIds.indexOf(route.id);
+ const isRouteExpanded = this.$refs.rightPanel ? this.$refs.rightPanel.expandedRoutes.includes(route.id) : false;
// 航线已在选中列表中
if (index > -1) {
- this.activeRouteIds.splice(index, 1);
- if (this.$refs.cesiumMap) {
- this.$refs.cesiumMap.removeRouteById(route.id);
- }
- if (this.selectedRouteDetails && this.selectedRouteDetails.id === route.id) {
- if (this.activeRouteIds.length > 0) {
- const lastId = this.activeRouteIds[this.activeRouteIds.length - 1];
- try {
- const res = await getRoutes(lastId);
- if (res.code === 200 && res.data) {
- this.selectedRouteDetails = {
- id: res.data.id,
- name: res.data.callSign,
- waypoints: res.data.waypoints || []
- };
+ if (isRouteExpanded) {
+ // 航线已展开,点击则收回航点(不取消选中)
+ // 这个逻辑在 RightPanel 的 toggleRoute 中处理
+ return;
+ } else {
+ // 航线未展开,点击则取消选中(从地图移除)
+ this.activeRouteIds.splice(index, 1);
+ if (this.$refs.cesiumMap) {
+ this.$refs.cesiumMap.removeRouteById(route.id);
+ }
+ if (this.selectedRouteDetails && this.selectedRouteDetails.id === route.id) {
+ if (this.activeRouteIds.length > 0) {
+ const lastId = this.activeRouteIds[this.activeRouteIds.length - 1];
+ try {
+ const res = await getRoutes(lastId);
+ if (res.code === 200 && res.data) {
+ this.selectedRouteId = res.data.id;
+ this.selectedRouteDetails = {
+ id: res.data.id,
+ name: res.data.callSign,
+ waypoints: res.data.waypoints || []
+ };
+ }
+ } catch (e) {
+ console.error("回显剩余航线失败", e);
}
- } catch (e) {
- console.error("回显剩余航线失败", e);
+ } else {
+ this.selectedRouteId = null;
+ this.selectedRouteDetails = null;
}
- } else {
- this.selectedRouteDetails = null;
}
+ this.$message.info(`已取消航线: ${route.name}`);
+ return;
}
- this.$message.info(`已移除航线: ${route.name}`);
- return;
}
- // 航线未被选中
+
+ // 航线未被选中,点击则选中并显示航线和航点
try {
const response = await getRoutes(route.id);
if (response.code === 200 && response.data) {
const fullRouteData = response.data;
const waypoints = fullRouteData.waypoints || [];
this.activeRouteIds.push(route.id);
- this.selectedRouteDetails = {
- id: fullRouteData.id,
- name: fullRouteData.callSign,
- waypoints: waypoints
- };
+ this.selectedRouteId = fullRouteData.id;
+ this.selectedRouteDetails = {
+ id: fullRouteData.id,
+ name: fullRouteData.callSign,
+ waypoints: waypoints
+ };
+
+ // 更新 routes 数组中对应航线的 waypoints 字段
+ const routeIndex = this.routes.findIndex(r => r.id === route.id);
+ if (routeIndex > -1) {
+ this.$set(this.routes, routeIndex, {
+ ...this.routes[routeIndex],
+ waypoints: waypoints
+ });
+ }
+
if (waypoints.length > 0) {
// 通知地图渲染
if (this.$refs.cesiumMap) {
@@ -1229,6 +1273,44 @@ export default {
this.$message.info('已清空所有选中航线');
},
+ // 切换航线显示/隐藏
+ toggleRouteVisibility(route) {
+ const index = this.activeRouteIds.indexOf(route.id);
+
+ if (index > -1) {
+ // 航线已显示,隐藏它
+ // 使用过滤创建新数组,确保 Vue 能够检测到变化
+ this.activeRouteIds = this.activeRouteIds.filter(id => id !== route.id);
+ if (this.$refs.cesiumMap) {
+ this.$refs.cesiumMap.removeRouteById(route.id);
+ }
+ if (this.selectedRouteDetails && this.selectedRouteDetails.id === route.id) {
+ if (this.activeRouteIds.length > 0) {
+ const lastId = this.activeRouteIds[this.activeRouteIds.length - 1];
+ getRoutes(lastId).then(res => {
+ if (res.code === 200 && res.data) {
+ this.selectedRouteId = res.data.id;
+ this.selectedRouteDetails = {
+ id: res.data.id,
+ name: res.data.callSign,
+ waypoints: res.data.waypoints || []
+ };
+ }
+ }).catch(e => {
+ console.error("获取航线详情失败", e);
+ });
+ } else {
+ this.selectedRouteId = null;
+ this.selectedRouteDetails = null;
+ }
+ }
+ this.$message.info(`已隐藏航线: ${route.name}`);
+ } else {
+ // 航线已隐藏,显示它
+ this.selectRoute(route);
+ }
+ },
+
// 冲突操作
runConflictCheck() {
this.conflictCount = 2;