From 0470eaa64cb4dabe7ab9096d7075a2ba89859d7c Mon Sep 17 00:00:00 2001
From: ctw <1051735452@qq.com>
Date: Tue, 20 Jan 2026 16:00:27 +0800
Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=88=AA=E7=82=B9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
ruoyi-ui/src/views/childRoom/index.vue | 1446 ++++++++++++++++++++++++++++----
1 file changed, 1276 insertions(+), 170 deletions(-)
diff --git a/ruoyi-ui/src/views/childRoom/index.vue b/ruoyi-ui/src/views/childRoom/index.vue
index 8069136..03d9f94 100644
--- a/ruoyi-ui/src/views/childRoom/index.vue
+++ b/ruoyi-ui/src/views/childRoom/index.vue
@@ -2,18 +2,105 @@
-
+
+
+
二维GIS地图区域
支持标绘/航线/空域/实时态势
-
+
+
+ 正在绘制: {{ pendingRoute.name }}
+ |
+ 已添加航点: {{ pendingRoute.points.length }}
+ 左键点击添加航点,右键结束
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
-
联合任务筹划系统
-
+
-
+
@@ -230,7 +317,7 @@
{{ onlineCount }}人
-
+
@@ -239,7 +326,7 @@
{{ combatTime }}
-
+
@@ -249,7 +336,7 @@
-
+
@@ -259,64 +346,314 @@
-
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+ 方案
+
+
+
+
+
+ 冲突
+ {{ conflictCount }}
+
+
+
+
+
+ 平台
+
+
+
+
+
+
+
+
+
+
+
+
{{ route.name }}
+
{{ route.points }}个航点
+
+
+ 冲突
+
+
+
+
+
+
+
+
+
+
+
航点列表
+
+
+
+
+
{{ point.name }}
+
高度: {{ point.altitude }}m | 速度: {{ point.speed }}
+
+
+
+
+
+
+
+
+
+
+
+ 添加航点
+
+
+ 取消
+
+
+
+
+
+
+
+
+
+
+
+ 涉及航线:
+ {{ conflict.routes.join('、') }}
+
+
+ 冲突时间:
+ {{ conflict.time }}
+
+
+ 冲突位置:
+ {{ conflict.position }}
+
+
+
+
+ 查看详情
+
+
+ 解决冲突
+
+
+
+
+
+
+
+
+
+
-
-
+
{{ currentTime }}
-
+
-
-
+
K-02:00
K-01:00
@@ -325,7 +662,7 @@
K+02:00
-
+
网络延迟:
@@ -341,32 +678,79 @@
-
+
-
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -376,8 +760,6 @@ import OnlineMembersDialog from '@/views/dialogs/OnlineMembersDialog'
import PlatformEditDialog from '@/views/dialogs/PlatformEditDialog'
import RouteEditDialog from '@/views/dialogs/RouteEditDialog'
import WaypointEditDialog from '@/views/dialogs/WaypointEditDialog'
-import LeftMenu from './LeftMenu'
-import RightPanel from './RightPanel'
export default {
name: 'MissionPlanningView',
components: {
@@ -385,9 +767,7 @@ export default {
OnlineMembersDialog,
PlatformEditDialog,
RouteEditDialog,
- WaypointEditDialog,
- LeftMenu,
- RightPanel
+ WaypointEditDialog
},
data() {
return {
@@ -401,6 +781,35 @@ export default {
selectedRoute: null,
showWaypointDialog: false,
selectedWaypoint: null,
+ //航线绘制相关数据
+ isDrawing: false, // 是否处于地图绘制模式
+ showCreateRouteDialog: false, // 是否显示"新建航线"弹窗
+ showWaypointDialog: false, // 是否显示"航点信息"弹窗
+
+ // 暂存正在创建的航线对象
+ pendingRoute: {
+ id: null,
+ name: '',
+ startTime: '',
+ points: []
+ },
+ // 暂存当前点击地图生成的临时航点坐标
+ tempClickPosition: null,
+
+ // 航点表单数据
+ waypointForm: {
+ name: '',
+ altitude: 0,
+ speed: 0,
+ time: '',
+ radius: 0
+ },
+
+ // 航点表单校验规则(可选)
+ waypointRules: {
+ name: [{ required: true, message: '请输入名称', trigger: 'blur' }],
+ altitude: [{ required: true, message: '请输入高度', trigger: 'blur' }]
+ },
// 顶部导航
activeTopNav: 'file',
topNavItems: [
@@ -413,23 +822,25 @@ export default {
{ id: 'options', name: '选项', icon: 'el-icon-s-tools' },
{ id: 'favorites', name: '收藏', icon: 'el-icon-star-on' }
],
-
+
// 作战信息
roomCode: 'JTF-7-ALPHA',
onlineCount: 30,
combatTime: 'K+01:30:45',
astroTime: '',
-
+
// 左侧菜单栏
isMenuHidden: true, // 是否完全隐藏左侧菜单
activeMenu: 'file',
-
+ hoverMenu: '',
+ showMenuTooltip: false,
+
// 右侧面板控制
isRightPanelHidden: true, // 是否完全隐藏右侧面板
-
+
// K时弹出框控制
showKTimePopup: false,
-
+
menuItems: [
{ id: 'file', name: '文件', icon: 'el-icon-document' },
{ id: 'start', name: '开始', icon: 'el-icon-caret-right' },
@@ -442,12 +853,12 @@ export default {
{ id: 'import', name: '导入', icon: 'el-icon-upload2' },
{ id: 'export', name: '导出', icon: 'el-icon-download' }
],
-
+
// 右侧面板
activeRightTab: 'plan',
selectedRouteId: 101,
selectedRouteDetails: null,
-
+
// 冲突数据
conflictCount: 2,
conflicts: [
@@ -468,7 +879,7 @@ export default {
severity: 'medium'
}
],
-
+
// 平台数据
activePlatformTab: 'air',
airPlatforms: [
@@ -487,18 +898,18 @@ export default {
{ id: 9, name: 'PLZ-05自行火炮', type: '自行火炮', icon: 'el-icon-aim', color: '#fa8c16', status: 'ready' },
{ id: 10, name: '指挥控制车', type: '指挥车', icon: 'el-icon-monitor', color: '#1890ff', status: 'operating' },
],
-
+
// 航线数据
routes: [
{ id: 101, name: 'Alpha进场航线', points: 8, conflict: true },
{ id: 102, name: 'Beta巡逻航线', points: 6, conflict: false },
{ id: 103, name: '侦察覆盖区', points: 4, conflict: false },
],
-
+
// 时间控制
timeProgress: 45,
currentTime: 'K+01:15:30',
-
+
// 用户
userAvatar: 'https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png',
};
@@ -508,7 +919,7 @@ export default {
this.isMenuHidden = true;
// 初始化时右侧面板隐藏
this.isRightPanelHidden = true;
-
+
// 更新时间
this.updateTime();
setInterval(this.updateTime, 1000);
@@ -516,6 +927,85 @@ export default {
setInterval(this.updateCombatTime, 1000);
},
methods: {
+// 添加新航线
+ addRoute() {
+ this.pendingRoute = {
+ id: Date.now(), // 生成唯一ID
+ name: '新建计划航线',
+ startTime: '',
+ points: []
+ };
+ this.showCreateRouteDialog = true;
+ },
+ // 2. 确认航线基本信息,进入“绘图模式”
+ confirmCreateRoute() {
+ if (!this.pendingRoute.name) {
+ this.$message.warning('请输入航线名称');
+ return;
+ }
+ this.showCreateRouteDialog = false;
+ this.isDrawing = true;
+ this.$message.info('进入绘制模式:左键点击地图添加航点,右键结束绘制');
+ },
+ // 3. 【核心】地图点击事件处理
+ // 注意:这个方法需要绑定到地图容器的 @click 上,或者在你的 cesiumMap 组件回调里调用
+ handleMapClick(event) {
+ if (!this.isDrawing) return;
+
+ // 模拟获取点击的经纬度,实际项目中请从 cesium 事件中获取
+ // const position = event.position || { lat: 30, lng: 120 };
+
+ // 暂存位置,打开航点录入弹窗
+ // this.tempClickPosition = position;
+
+ // 重置表单,自动生成默认值
+ const nextIndex = this.pendingRoute.points.length + 1;
+ this.waypointForm = {
+ name: `WP-${nextIndex}`,
+ altitude: 5000,
+ speed: 800,
+ time: '',
+ radius: 5
+ };
+
+ this.showWaypointDialog = true;
+ },
+ // 4. 确认添加一个航点
+ confirmWaypoint() {
+ // 将表单数据和位置信息合并
+ const newPoint = {
+ ...this.waypointForm,
+ // ...this.tempClickPosition // 这里存入真实的经纬度
+ };
+
+ this.pendingRoute.points.push(newPoint);
+ this.showWaypointDialog = false;
+ this.$message.success(`已添加第 ${this.pendingRoute.points.length} 个航点`);
+ },
+ // 5. 右键结束绘制
+ finishDrawing() {
+ if (!this.isDrawing) return;
+
+ if (this.pendingRoute.points.length < 2) {
+ this.$message.warning('航线至少需要2个航点');
+ return;
+ }
+
+ // 构造最终数据格式,推入主数组
+ const finalRoute = {
+ id: this.pendingRoute.id,
+ name: this.pendingRoute.name,
+ points: this.pendingRoute.points.length, // 显示航点数量
+ conflict: false,
+ detailData: this.pendingRoute // 保存完整数据以便后续使用
+ };
+
+ this.routes.push(finalRoute);
+ this.isDrawing = false;
+ this.selectRoute(finalRoute); // 选中新航线
+ this.$message.success('航线绘制完成!');
+ },
+
// 显示在线成员弹窗
showOnlineMembersDialog() {
this.showOnlineMembers = true;
@@ -557,7 +1047,7 @@ export default {
const seconds = now.getSeconds().toString().padStart(2, '0');
this.astroTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
},
-
+
updateCombatTime() {
// 模拟作战时间(K时)的更新
// 这里简单模拟,实际应该根据业务逻辑计算
@@ -565,226 +1055,226 @@ export default {
const baseSeconds = 5400; // 1小时30分钟 = 5400秒
const currentSeconds = now.getSeconds() + now.getMinutes() * 60 + now.getHours() * 3600;
const combatSeconds = baseSeconds + (currentSeconds % 86400);
-
+
const hours = Math.floor(combatSeconds / 3600);
const minutes = Math.floor((combatSeconds % 3600) / 60);
const seconds = combatSeconds % 60;
-
+
this.combatTime = `K+${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
},
-
+
// 顶部导航菜单操作
selectTopNav(item) {
this.activeTopNav = item.id;
this.$message.info(`选择菜单: ${item.name}`);
},
-
+
// 左侧菜单栏操作
showMenu() {
this.isMenuHidden = false;
this.$message.info('显示左侧菜单');
},
-
+
hideMenu() {
this.isMenuHidden = true;
this.$message.info('隐藏左侧菜单');
},
-
+
// 右侧面板操作
showRightPanel() {
this.isRightPanelHidden = false;
this.$message.info('显示右侧面板');
},
-
+
// 文件下拉菜单方法
newPlan() {
this.$message.success('新建计划');
// 这里可以添加新建计划的逻辑
},
-
+
openPlan() {
this.$message.success('打开计划');
// 这里可以添加打开计划的逻辑
},
-
+
savePlan() {
this.$message.success('保存计划');
// 这里可以添加保存计划的逻辑
},
-
+
importPlan() {
this.$message.success('导入计划');
// 这里可以添加导入计划的逻辑
},
-
+
// 导入二级菜单方法
importPlanFile() {
this.$message.success('导入计划');
// 这里可以添加导入计划文件的逻辑
},
-
+
importACD() {
this.$message.success('导入ACD');
// 这里可以添加导入ACD文件的逻辑
},
-
+
importATO() {
this.$message.success('导入ATO');
// 这里可以添加导入ATO文件的逻辑
},
-
+
importLayer() {
this.$message.success('导入图层');
// 这里可以添加导入图层的逻辑
},
-
+
importRoute() {
this.$message.success('导入航线');
// 这里可以添加导入航线的逻辑
},
-
+
exportPlan() {
this.$message.success('导出计划');
// 这里可以添加导出计划的逻辑
},
-
+
// 编辑下拉菜单方法
routeEdit() {
this.$message.success('航线编辑');
// 这里可以添加航线编辑的逻辑
},
-
+
militaryMarking() {
this.$message.success('军事标绘');
// 这里可以添加军事标绘的逻辑
},
-
+
iconEdit() {
this.$message.success('图标编辑');
// 这里可以添加图标编辑的逻辑
},
-
+
attributeEdit() {
this.$message.success('属性修改');
// 这里可以添加属性修改的逻辑
},
-
+
deductionEdit() {
this.$message.success('推演编辑');
// 这里可以添加推演编辑的逻辑
},
-
+
// 推演编辑二级菜单方法
timeSettings() {
this.$message.success('时间设置');
// 这里可以添加时间设置的逻辑
},
-
+
aircraftSettings() {
this.$message.success('机型设置');
// 这里可以添加机型设置的逻辑
},
-
+
keyEventEdit() {
this.$message.success('关键事件编辑');
// 这里可以添加关键事件编辑的逻辑
},
-
+
missileLaunch() {
this.$message.success('导弹发射');
// 这里可以添加导弹发射的逻辑
},
-
+
// 视图下拉菜单方法
toggle2D3D() {
this.$message.success('2D/3D切换');
// 这里可以添加2D/3D切换的逻辑
},
-
+
toggleRuler() {
this.$message.success('显示/隐藏标尺');
// 这里可以添加标尺显示/隐藏的逻辑
},
-
+
toggleGrid() {
this.$message.success('显示/隐藏网格');
// 这里可以添加网格显示/隐藏的逻辑
},
-
+
toggleScale() {
this.$message.success('显示/隐藏比例尺');
// 这里可以添加比例尺显示/隐藏的逻辑
},
-
+
toggleCompass() {
this.$message.success('显示/隐藏指北针');
// 这里可以添加指北针显示/隐藏的逻辑
},
-
+
// 地图下拉菜单方法
loadTerrain() {
this.$message.success('加载/切换地形');
// 这里可以添加地形加载/切换的逻辑
},
-
+
changeProjection() {
this.$message.success('投影');
// 这里可以添加投影切换的逻辑
},
-
+
loadAeroChart() {
this.$message.success('航空图');
// 这里可以添加航空图加载的逻辑
},
-
+
// 工具下拉菜单方法
routeCalculation() {
this.$message.success('航线计算');
// 这里可以添加航线计算的逻辑
},
-
+
conflictDisplay() {
this.$message.success('冲突显示');
// 这里可以添加冲突显示的逻辑
},
-
+
dataMaterials() {
this.$message.success('数据资料');
// 这里可以添加数据资料管理的逻辑
},
-
+
coordinateConversion() {
this.$message.success('坐标换算');
// 这里可以添加坐标换算的逻辑
},
-
+
// 选项下拉菜单方法
settings() {
this.$message.success('设置');
// 这里可以添加系统设置的逻辑
},
-
+
systemDescription() {
this.$message.success('系统说明');
// 这里可以添加系统说明的逻辑
},
-
+
// 收藏下拉菜单方法
layerFavorites() {
this.$message.success('图层收藏');
// 这里可以添加图层收藏的逻辑
},
-
+
routeFavorites() {
this.$message.success('航线收藏');
// 这里可以添加航线收藏的逻辑
},
-
+
hideRightPanel() {
this.isRightPanelHidden = true;
this.$message.info('隐藏右侧面板');
},
-
+
selectMenu(item) {
this.activeMenu = item.id;
if(item.id === 'modify'){
@@ -802,37 +1292,50 @@ export default {
} else {
// 其他菜单的原有逻辑
this.$message.info(`选择菜单: ${item.name}`);
-
+
}
},
-
+
+ showTooltip(item) {
+ this.hoverMenu = item.id;
+ },
+
+ hideTooltip() {
+ this.hoverMenu = '';
+ },
+
+ getMenuName(id) {
+ const menu = this.menuItems.find(item => item.id === id);
+ return menu ? menu.name : '';
+ },
+
// K时弹出框操作
hideKTimePopup() {
this.showKTimePopup = false;
this.$message.info('隐藏推演时钟控制');
},
-
+
// 时间控制(保留用于底部时间轴)
play() {
this.$message.success('推演开始');
},
-
+
pause() {
this.$message.info('推演暂停');
},
-
+
reset() {
this.timeProgress = 0;
this.currentTime = 'K+00:00:00';
this.$message.info('推演已重置');
},
-
+
formatTimeTooltip(val) {
const hours = Math.floor(val / 4);
const minutes = (val % 4) * 15;
return `K+${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:00`;
},
-
+
// 航线操作
selectRoute(route) {
this.selectedRouteId = route.id;
@@ -849,7 +1352,7 @@ export default {
// 打开航线编辑弹窗
this.openRouteDialog(route);
},
-
+
addWaypoint() {
if (this.selectedRouteDetails) {
const count = this.selectedRouteDetails.waypoints.length + 1;
@@ -862,35 +1365,35 @@ export default {
this.$message.success('添加航点成功');
}
},
-
+
cancelRoute() {
this.selectedRouteId = null;
this.selectedRouteDetails = null;
this.$message.info('已取消选中');
},
-
+
// 冲突操作
runConflictCheck() {
this.conflictCount = 2;
this.$message.warning('检测到2处航线冲突');
},
-
+
viewConflict(conflict) {
this.$message.info(`查看冲突:${conflict.title}`);
},
-
+
resolveConflict(conflict) {
this.$message.success(`解决冲突:${conflict.title}`);
// 移除已解决的冲突
this.conflicts = this.conflicts.filter(c => c.id !== conflict.id);
this.conflictCount = this.conflicts.length;
},
-
+
// 系统功能
exportReport() {
this.$message.success('作战报表导出成功');
},
-
+
// 新增导入功能
importData() {
this.$message.success('导入数据成功');
@@ -1265,6 +1768,609 @@ background: url('~@/assets/map-background.png');
border-color: rgba(0, 138, 255, 0.6);
}
+/* 左侧菜单栏 - 蓝色主题 */
+.floating-left-menu {
+ position: absolute;
+ top: 70px;
+ left: 20px;
+ width: 40px;
+ background: rgba(255, 255, 255, 0.3);
+ backdrop-filter: blur(10px);
+ border: 1px solid rgba(0, 138, 255, 0.1);
+ border-radius: 8px;
+ z-index: 90;
+ box-shadow: 0 4px 12px rgba(0, 138, 255, 0.2);
+ padding: 15px 5px;
+ transition: all 0.3s ease;
+ overflow: hidden;
+ opacity: 1;
+ transform: translateX(0);
+}
+
+.floating-left-menu.hidden {
+ opacity: 0;
+ transform: translateX(-100%);
+ pointer-events: none;
+}
+
+.hide-btn {
+ position: absolute;
+ top: 15px;
+ left: 50%;
+ transform: translateX(-50%);
+ width: 24px;
+ height: 24px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ cursor: pointer;
+ color: #008aff;
+ font-size: 16px;
+ transition: all 0.3s;
+ background: rgba(255, 255, 255, 0.5);
+ border-radius: 4px;
+ z-index: 10;
+}
+
+.hide-btn:hover {
+ color: #0066cc;
+ background: rgba(0, 138, 255, 0.1);
+ transform: scale(1.1);
+}
+
+.menu-icons {
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+ margin-top: 30px;
+}
+
+.menu-item {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ height: 40px;
+ cursor: pointer;
+ color: #555;
+ font-size: 20px;
+ position: relative;
+ transition: all 0.3s;
+ border-radius: 4px;
+ padding: 0 5px;
+ background: rgba(255, 255, 255, 0.8);
+ backdrop-filter: blur(5px);
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+}
+
+.menu-item:hover {
+ background: rgba(0, 138, 255, 0.1);
+ color: #008aff;
+ transform: translateY(-2px);
+ box-shadow: 0 4px 10px rgba(0, 138, 255, 0.2);
+}
+
+.menu-item.active {
+ background: linear-gradient(135deg, rgba(0, 138, 255, 0.2), rgba(0, 138, 255, 0.3));
+ color: #008aff;
+ box-shadow: 0 4px 12px rgba(0, 138, 255, 0.25);
+}
+
+.menu-tooltip {
+ position: absolute;
+ left: 100%;
+ top: 50%;
+ transform: translateY(-50%);
+ background: linear-gradient(135deg, rgba(0, 138, 255, 0.95), rgba(0, 102, 204, 0.95));
+ color: white;
+ padding: 8px 14px;
+ border-radius: 6px;
+ font-size: 12px;
+ white-space: nowrap;
+ z-index: 1000;
+ margin-left: 10px;
+ box-shadow: 0 4px 12px rgba(0, 138, 255, 0.3);
+ pointer-events: none;
+ backdrop-filter: blur(5px);
+}
+
+.menu-tooltip-layer {
+ position: absolute;
+ top: 0;
+ left: 100%;
+ width: 200px;
+ height: 100%;
+ z-index: 999;
+ pointer-events: none;
+}
+
+.tooltip-content {
+ position: absolute;
+ top: 50%;
+ left: 0;
+ transform: translateY(-50%);
+ background: linear-gradient(135deg, rgba(0, 138, 255, 0.95), rgba(0, 102, 204, 0.95));
+ color: white;
+ padding: 8px 14px;
+ border-radius: 6px;
+ font-size: 12px;
+ white-space: nowrap;
+ margin-left: 10px;
+ box-shadow: 0 4px 12px rgba(0, 138, 255, 0.3);
+ backdrop-filter: blur(5px);
+}
+
+/* 右侧外部隐藏按钮 */
+.right-external-hide-btn {
+ position: absolute;
+ top: 70px;
+ right: 320px; /* 面板宽度300px + 外边距20px */
+ width: 28px;
+ height: 40px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ cursor: pointer;
+ color: white;
+ font-size: 16px;
+ transition: all 0.3s;
+ background: rgba(0, 138, 255, 0.9);
+ border-radius: 8px 0 0 8px;
+ z-index: 91;
+ border: 1px solid rgba(0, 138, 255, 1);
+ border-right: none;
+ box-shadow: -2px 0 8px rgba(0, 138, 255, 0.3);
+ opacity: 1;
+ transform: translateX(0);
+}
+
+.right-external-hide-btn:hover {
+ background: rgba(0, 138, 255, 1);
+ transform: translateX(-2px);
+ box-shadow: -4px 0 12px rgba(0, 138, 255, 0.5);
+}
+
+.right-external-hide-btn.hidden {
+ opacity: 0;
+ pointer-events: none;
+ transform: translateX(20px);
+}
+
+/* 右侧浮动面板 - 蓝色主题 */
+.floating-right-panel {
+ position: absolute;
+ top: 70px;
+ right: 20px;
+ width: 300px;
+ border-radius: 0 8px 8px 8px;
+ z-index: 90;
+ color: #333;
+ overflow: hidden;
+ box-shadow: 0 4px 20px rgba(0, 138, 255, 0.2);
+ background: rgba(255, 255, 255, 0.95);
+ backdrop-filter: blur(15px);
+ transition: all 0.3s ease;
+ opacity: 1;
+ transform: translateX(0);
+}
+
+.floating-right-panel.hidden {
+ opacity: 0;
+ transform: translateX(100%);
+ pointer-events: none;
+}
+
+.right-tabs {
+ display: flex;
+ border-bottom: 1px solid rgba(0, 138, 255, 0.3);
+ background: rgba(255, 255, 255, 0.9);
+ backdrop-filter: blur(5px);
+}
+
+.right-tab-item {
+ flex: 1;
+ text-align: center;
+ padding: 12px 0;
+ cursor: pointer;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 4px;
+ transition: all 0.3s;
+ position: relative;
+ border-bottom: 3px solid transparent;
+ background: rgba(255, 255, 255, 0.8);
+ backdrop-filter: blur(5px);
+}
+
+.right-tab-item i {
+ font-size: 18px;
+ color: #666;
+ transition: all 0.3s;
+}
+
+.right-tab-item span {
+ font-size: 12px;
+ color: #666;
+ transition: all 0.3s;
+}
+
+.right-tab-item:hover {
+ background: rgba(0, 138, 255, 0.1);
+ box-shadow: 0 2px 6px rgba(0, 138, 255, 0.15);
+}
+
+.right-tab-item.active {
+ background: rgba(255, 255, 255, 0.95);
+ border-bottom: 3px solid rgba(0, 138, 255, 0.8);
+ box-shadow: 0 2px 8px rgba(0, 138, 255, 0.2);
+}
+
+.right-tab-item.active i,
+.right-tab-item.active span {
+ color: #008aff;
+ font-weight: 600;
+ text-shadow: 0 0 2px rgba(0, 138, 255, 0.3);
+}
+
+.badge {
+ position: absolute;
+ top: 8px;
+ right: 20px;
+ border-radius: 10px;
+ padding: 2px 8px;
+ font-size: 10px;
+ min-width: 16px;
+ text-align: center;
+ backdrop-filter: blur(5px);
+ box-shadow: 0 2px 4px rgba(0, 138, 255, 0.3);
+}
+
+.tab-content {
+ padding: 15px;
+ max-height: 500px;
+ overflow-y: auto;
+ background: rgba(255, 255, 255, 0.95);
+ backdrop-filter: blur(10px);
+}
+
+.section {
+ margin-bottom: 20px;
+}
+
+.section-title {
+ font-size: 12px;
+ color: #666;
+ margin-bottom: 10px;
+ padding-bottom: 6px;
+ border-bottom: 1px solid rgba(0, 138, 255, 0.3);
+ font-weight: 600;
+}
+
+.route-list {
+ margin-bottom: 20px;
+}
+
+.route-item {
+ display: flex;
+ align-items: center;
+ padding: 10px;
+ border-radius: 6px;
+ margin-bottom: 6px;
+ cursor: pointer;
+ transition: all 0.3s;
+ border: 1px solid transparent;
+ background: rgba(255, 255, 255, 0.9);
+ backdrop-filter: blur(5px);
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+}
+
+.route-item:hover {
+ background: rgba(0, 138, 255, 0.1);
+ border-color: rgba(0, 138, 255, 0.3);
+ transform: translateY(-1px);
+ box-shadow: 0 4px 10px rgba(0, 138, 255, 0.15);
+}
+
+.route-item.selected {
+ background: linear-gradient(135deg, rgba(0, 138, 255, 0.15), rgba(0, 138, 255, 0.25));
+ border-color: rgba(0, 138, 255, 0.4);
+ box-shadow: 0 4px 12px rgba(0, 138, 255, 0.2);
+}
+
+.route-item i {
+ font-size: 18px;
+ color: #008aff;
+ margin-right: 10px;
+ text-shadow: 0 0 4px rgba(0, 138, 255, 0.3);
+}
+
+.route-info {
+ flex: 1;
+}
+
+.route-name {
+ font-size: 13px;
+ color: #333;
+ margin-bottom: 3px;
+ font-weight: 600;
+}
+
+.route-meta {
+ font-size: 11px;
+ color: #666;
+}
+
+.conflict-tag {
+ background: linear-gradient(135deg, #f56c6c, #c45656);
+ border: none;
+ color: white;
+ backdrop-filter: blur(5px);
+ box-shadow: 0 2px 4px rgba(245, 108, 108, 0.3);
+}
+
+.waypoint-list {
+ margin-bottom: 15px;
+}
+
+.waypoint-item {
+ display: flex;
+ align-items: center;
+ padding: 10px;
+ border-radius: 6px;
+ margin-bottom: 6px;
+ background: rgba(255, 255, 255, 0.9);
+ border: 1px solid rgba(0, 138, 255, 0.3);
+ backdrop-filter: blur(5px);
+ box-shadow: 0 2px 4px rgba(0, 138, 255, 0.1);
+ transition: all 0.3s;
+}
+
+.waypoint-item:hover {
+ transform: translateY(-1px);
+ box-shadow: 0 4px 10px rgba(0, 138, 255, 0.15);
+}
+
+.waypoint-item i {
+ font-size: 18px;
+ color: #52c41a;
+ margin-right: 10px;
+ text-shadow: 0 0 4px rgba(82, 196, 26, 0.3);
+}
+
+.waypoint-info {
+ flex: 1;
+}
+
+.waypoint-name {
+ font-size: 13px;
+ color: #333;
+ margin-bottom: 3px;
+ font-weight: 600;
+}
+
+.waypoint-meta {
+ font-size: 11px;
+ color: #666;
+}
+
+.waypoint-actions {
+ display: flex;
+ gap: 10px;
+ color: #666;
+}
+
+.waypoint-actions i {
+ cursor: pointer;
+ font-size: 14px;
+ transition: all 0.3s;
+ padding: 4px;
+ border-radius: 4px;
+ background: rgba(255, 255, 255, 0.8);
+ backdrop-filter: blur(5px);
+}
+
+.waypoint-actions i:hover {
+ color: #008aff;
+ transform: scale(1.1);
+ box-shadow: 0 2px 6px rgba(0, 138, 255, 0.2);
+}
+
+.action-buttons {
+ display: flex;
+ gap: 10px;
+ justify-content: center;
+}
+
+/* 按钮样式调整 */
+.el-button {
+ backdrop-filter: blur(5px);
+ transition: all 0.3s;
+}
+
+/* 冲突内容样式 */
+.conflict-list {
+ display: flex;
+ flex-direction: column;
+ gap: 15px;
+}
+
+.conflict-item {
+ background: linear-gradient(135deg, rgba(245, 108, 108, 0.1), rgba(245, 108, 108, 0.05));
+ border: 1px solid rgba(245, 108, 108, 0.3);
+ border-radius: 8px;
+ padding: 14px;
+ backdrop-filter: blur(5px);
+ box-shadow: 0 4px 10px rgba(245, 108, 108, 0.15);
+ transition: all 0.3s;
+}
+
+.conflict-item:hover {
+ transform: translateY(-2px);
+ box-shadow: 0 6px 15px rgba(245, 108, 108, 0.2);
+}
+
+.conflict-header {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ margin-bottom: 10px;
+}
+
+.conflict-title {
+ flex: 1;
+ font-size: 13px;
+ color: #333;
+ font-weight: 700;
+}
+
+.conflict-details {
+ background: rgba(255, 255, 255, 0.8);
+ border-radius: 6px;
+ padding: 10px;
+ margin-bottom: 10px;
+ border: 1px solid rgba(255, 255, 255, 0.4);
+ backdrop-filter: blur(5px);
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
+}
+
+.detail-item {
+ display: flex;
+ margin-bottom: 5px;
+ font-size: 12px;
+}
+
+.detail-item:last-child {
+ margin-bottom: 0;
+}
+
+.detail-item .label {
+ color: #666;
+ min-width: 70px;
+ font-weight: 500;
+}
+
+.detail-item .value {
+ color: #333;
+ flex: 1;
+ font-weight: 600;
+}
+
+.conflict-actions {
+ display: flex;
+ justify-content: flex-end;
+ gap: 15px;
+}
+
+.no-conflict {
+ text-align: center;
+ padding: 40px 20px;
+ color: #666;
+}
+
+.no-conflict p {
+ margin: 10px 0 15px;
+}
+
+/* 平台内容样式 */
+.platform-list {
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+}
+
+.platform-item {
+ display: flex;
+ align-items: center;
+ padding: 12px;
+ border-radius: 6px;
+ background: rgba(255, 255, 255, 0.9);
+ border: 1px solid rgba(0, 138, 255, 0.3);
+ transition: all 0.3s;
+ backdrop-filter: blur(5px);
+ box-shadow: 0 2px 6px rgba(0, 138, 255, 0.1);
+}
+
+.platform-item:hover {
+ background: rgba(0, 138, 255, 0.1);
+ border-color: rgba(0, 138, 255, 0.4);
+ transform: translateY(-2px);
+ box-shadow: 0 4px 12px rgba(0, 138, 255, 0.2);
+}
+
+.platform-icon {
+ width: 36px;
+ height: 36px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 22px;
+ margin-right: 12px;
+ border-radius: 6px;
+ background: rgba(255, 255, 255, 0.8);
+ backdrop-filter: blur(5px);
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
+}
+
+.platform-info {
+ flex: 1;
+}
+
+.platform-name {
+ font-size: 13px;
+ color: #333;
+ margin-bottom: 3px;
+ font-weight: 600;
+}
+
+.platform-type {
+ font-size: 11px;
+ color: #666;
+}
+
+.platform-status {
+ margin-left: 10px;
+}
+
+.status-dot {
+ display: inline-block;
+ width: 10px;
+ height: 10px;
+ border-radius: 50%;
+ box-shadow: 0 0 6px currentColor;
+}
+
+.status-dot.ready {
+ background: #52c41a;
+ box-shadow: 0 0 8px rgba(82, 196, 26, 0.8);
+}
+.status-dot.flying {
+ background: #008aff;
+ animation: pulse 2s infinite;
+ box-shadow: 0 0 10px rgba(0, 138, 255, 0.8);
+}
+.status-dot.scouting {
+ background: #fa8c16;
+ animation: pulse 1.5s infinite;
+ box-shadow: 0 0 10px rgba(250, 140, 22, 0.8);
+}
+.status-dot.sailing {
+ background: #008aff;
+ box-shadow: 0 0 8px rgba(0, 138, 255, 0.8);
+}
+.status-dot.patrol {
+ background: #52c41a;
+ animation: pulse 2s infinite;
+ box-shadow: 0 0 10px rgba(82, 196, 26, 0.8);
+}
+.status-dot.hidden {
+ background: #333;
+ box-shadow: 0 0 6px rgba(51, 51, 51, 0.8);
+}
+.status-dot.alert {
+ background: #f5222d;
+ animation: pulse 1s infinite;
+ box-shadow: 0 0 10px rgba(245, 34, 45, 0.8);
+}
/* 二级菜单样式 */
.submenu-item {
position: relative;
@@ -1379,9 +2485,9 @@ background: url('~@/assets/map-background.png');
position: relative;
}
-.status-dot.operating {
- background: #008aff;
- animation: pulse 2s infinite;
+.status-dot.operating {
+ background: #008aff;
+ animation: pulse 2s infinite;
box-shadow: 0 0 10px rgba(0, 138, 255, 0.8);
}