|
|
|
@ -259,276 +259,38 @@ |
|
|
|
</div> |
|
|
|
|
|
|
|
<!-- 左侧折叠菜单栏 - 蓝色主题 --> |
|
|
|
<div |
|
|
|
class="floating-left-menu" |
|
|
|
:class="{ 'hidden': isMenuHidden }" |
|
|
|
@mouseenter="showMenuTooltip = true" |
|
|
|
@mouseleave="showMenuTooltip = false" |
|
|
|
> |
|
|
|
<!-- 隐藏按钮(>箭头) --> |
|
|
|
<div class="hide-btn" @click="hideMenu" title="隐藏菜单" > |
|
|
|
<i class="el-icon-arrow-left"></i> |
|
|
|
</div> |
|
|
|
|
|
|
|
<!-- 一级菜单 --> |
|
|
|
<div class="menu-icons"> |
|
|
|
<div |
|
|
|
v-for="item in menuItems" |
|
|
|
:key="item.id" |
|
|
|
class="menu-item" |
|
|
|
:class="{ active: activeMenu === item.id }" |
|
|
|
@click="selectMenu(item)" |
|
|
|
@mouseenter="showTooltip(item)" |
|
|
|
@mouseleave="hideTooltip" |
|
|
|
> |
|
|
|
<i :class="item.icon"></i> |
|
|
|
<!-- 悬浮提示 --> |
|
|
|
<div v-if="showMenuTooltip && hoverMenu === item.id" class="menu-tooltip"> |
|
|
|
{{ item.name }} |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<!-- 菜单工具提示层(解决遮挡) --> |
|
|
|
<div v-if="showMenuTooltip && hoverMenu" class="menu-tooltip-layer"> |
|
|
|
<div class="tooltip-content">{{ getMenuName(hoverMenu) }}</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<!-- 右侧外部隐藏按钮 --> |
|
|
|
<div |
|
|
|
class="right-external-hide-btn" |
|
|
|
:class="{ hidden: isRightPanelHidden }" |
|
|
|
@click="hideRightPanel" |
|
|
|
title="隐藏右侧面板" |
|
|
|
> |
|
|
|
<i class="el-icon-arrow-right"></i> |
|
|
|
</div> |
|
|
|
<left-menu |
|
|
|
:is-hidden="isMenuHidden" |
|
|
|
:menu-items="menuItems" |
|
|
|
:active-menu="activeMenu" |
|
|
|
@hide="hideMenu" |
|
|
|
@select="selectMenu" |
|
|
|
/> |
|
|
|
|
|
|
|
<!-- 右侧实体列表(浮动)- 蓝色主题 --> |
|
|
|
<div |
|
|
|
class="floating-right-panel blue-theme" |
|
|
|
:class="{ 'hidden': isRightPanelHidden }" |
|
|
|
> |
|
|
|
<!-- 移除面板内部的隐藏按钮 --> |
|
|
|
|
|
|
|
<div class="right-tabs"> |
|
|
|
<!-- 方案 --> |
|
|
|
<div |
|
|
|
class="right-tab-item" |
|
|
|
:class="{ active: activeRightTab === 'plan' }" |
|
|
|
@click="activeRightTab = 'plan'" |
|
|
|
> |
|
|
|
<i class="el-icon-s-operation"></i> |
|
|
|
<span>方案</span> |
|
|
|
</div> |
|
|
|
|
|
|
|
<!-- 冲突 --> |
|
|
|
<div |
|
|
|
class="right-tab-item" |
|
|
|
:class="{ active: activeRightTab === 'conflict' }" |
|
|
|
@click="activeRightTab = 'conflict'" |
|
|
|
> |
|
|
|
<i class="el-icon-warning-outline"></i> |
|
|
|
<span>冲突</span> |
|
|
|
<span v-if="conflictCount > 0" class="badge blue-badge">{{ conflictCount }}</span> |
|
|
|
</div> |
|
|
|
|
|
|
|
<!-- 平台 --> |
|
|
|
<div |
|
|
|
class="right-tab-item" |
|
|
|
:class="{ active: activeRightTab === 'platform' }" |
|
|
|
@click="activeRightTab = 'platform'" |
|
|
|
> |
|
|
|
<i class="el-icon-ship"></i> |
|
|
|
<span>平台</span> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<!-- 方案内容 --> |
|
|
|
<div v-if="activeRightTab === 'plan'" class="tab-content plan-content"> |
|
|
|
<div class="section"> |
|
|
|
<div class="section-title">航线列表</div> |
|
|
|
<div class="route-list"> |
|
|
|
<div |
|
|
|
v-for="route in routes" |
|
|
|
:key="route.id" |
|
|
|
class="route-item" |
|
|
|
:class="{ selected: selectedRouteId === route.id }" |
|
|
|
@click="selectRoute(route)" |
|
|
|
> |
|
|
|
<i class="el-icon-map-location"></i> |
|
|
|
<div class="route-info"> |
|
|
|
<div class="route-name">{{ route.name }}</div> |
|
|
|
<div class="route-meta">{{ route.points }}个航点</div> |
|
|
|
</div> |
|
|
|
<el-tag |
|
|
|
v-if="route.conflict" |
|
|
|
size="mini" |
|
|
|
type="danger" |
|
|
|
class="conflict-tag" |
|
|
|
> |
|
|
|
冲突 |
|
|
|
</el-tag> |
|
|
|
<!-- 添加编辑按钮 --> |
|
|
|
<div class="route-actions"> |
|
|
|
<i class="el-icon-edit" title="编辑" @click.stop="openRouteDialog(route)"></i> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<div v-if="selectedRouteDetails" class="section"> |
|
|
|
<div class="section-title">航点列表</div> |
|
|
|
<div class="waypoint-list"> |
|
|
|
<div |
|
|
|
v-for="point in selectedRouteDetails.waypoints" |
|
|
|
:key="point.name" |
|
|
|
class="waypoint-item" |
|
|
|
@click="openWaypointDialog(point)" |
|
|
|
> |
|
|
|
<i class="el-icon-location"></i> |
|
|
|
<div class="waypoint-info"> |
|
|
|
<div class="waypoint-name">{{ point.name }}</div> |
|
|
|
<div class="waypoint-meta">高度: {{ point.altitude }}m | 速度: {{ point.speed }}</div> |
|
|
|
</div> |
|
|
|
<div class="waypoint-actions"> |
|
|
|
<i class="el-icon-edit" title="编辑" @click.stop="openWaypointDialog(point)"></i> |
|
|
|
<i class="el-icon-delete" title="删除"></i> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<div class="action-buttons"> |
|
|
|
<el-button type="primary" size="mini" icon="el-icon-circle-plus" class="blue-btn" @click="addWaypoint"> |
|
|
|
添加航点 |
|
|
|
</el-button> |
|
|
|
<el-button size="mini" class="blue-btn" @click="cancelRoute"> |
|
|
|
取消 |
|
|
|
</el-button> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<!-- 冲突内容 --> |
|
|
|
<div v-if="activeRightTab === 'conflict'" class="tab-content conflict-content"> |
|
|
|
<div v-if="conflicts.length > 0" class="conflict-list"> |
|
|
|
<div |
|
|
|
v-for="conflict in conflicts" |
|
|
|
:key="conflict.id" |
|
|
|
class="conflict-item" |
|
|
|
> |
|
|
|
<div class="conflict-header"> |
|
|
|
<i class="el-icon-warning" style="color: #f56c6c;"></i> |
|
|
|
<span class="conflict-title">{{ conflict.title }}</span> |
|
|
|
<el-tag size="mini" type="danger">严重</el-tag> |
|
|
|
</div> |
|
|
|
<div class="conflict-details"> |
|
|
|
<div class="detail-item"> |
|
|
|
<span class="label">涉及航线:</span> |
|
|
|
<span class="value">{{ conflict.routes.join('、') }}</span> |
|
|
|
</div> |
|
|
|
<div class="detail-item"> |
|
|
|
<span class="label">冲突时间:</span> |
|
|
|
<span class="value">{{ conflict.time }}</span> |
|
|
|
</div> |
|
|
|
<div class="detail-item"> |
|
|
|
<span class="label">冲突位置:</span> |
|
|
|
<span class="value">{{ conflict.position }}</span> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div class="conflict-actions"> |
|
|
|
<el-button type="text" size="mini" class="blue-text-btn" @click="viewConflict(conflict)"> |
|
|
|
查看详情 |
|
|
|
</el-button> |
|
|
|
<el-button type="text" size="mini" class="blue-text-btn" @click="resolveConflict(conflict)"> |
|
|
|
解决冲突 |
|
|
|
</el-button> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div v-else class="no-conflict"> |
|
|
|
<i class="el-icon-success" style="color: #67c23a; font-size: 24px;"></i> |
|
|
|
<p>暂无冲突</p> |
|
|
|
<el-button size="mini" class="blue-btn" @click="runConflictCheck"> |
|
|
|
重新检测 |
|
|
|
</el-button> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<!-- 平台内容 --> |
|
|
|
<div v-if="activeRightTab === 'platform'" class="tab-content platform-content"> |
|
|
|
<div class="platform-categories"> |
|
|
|
<el-tabs v-model="activePlatformTab" type="card" size="mini" class="blue-tabs"> |
|
|
|
<el-tab-pane label="空中" name="air"> |
|
|
|
<div class="platform-list"> |
|
|
|
<div |
|
|
|
v-for="platform in airPlatforms" |
|
|
|
:key="platform.id" |
|
|
|
class="platform-item" |
|
|
|
@click="openPlatformDialog(platform)" |
|
|
|
> |
|
|
|
<div class="platform-icon" :style="{ color: platform.color }"> |
|
|
|
<i :class="platform.icon"></i> |
|
|
|
</div> |
|
|
|
<div class="platform-info"> |
|
|
|
<div class="platform-name">{{ platform.name }}</div> |
|
|
|
<div class="platform-type">{{ platform.type }}</div> |
|
|
|
</div> |
|
|
|
<div class="platform-status"> |
|
|
|
<span class="status-dot" :class="platform.status"></span> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</el-tab-pane> |
|
|
|
|
|
|
|
<el-tab-pane label="海上" name="sea"> |
|
|
|
<div class="platform-list"> |
|
|
|
<div |
|
|
|
v-for="platform in seaPlatforms" |
|
|
|
:key="platform.id" |
|
|
|
class="platform-item" |
|
|
|
@click="openPlatformDialog(platform)" |
|
|
|
> |
|
|
|
<div class="platform-icon" :style="{ color: platform.color }"> |
|
|
|
<i :class="platform.icon"></i> |
|
|
|
</div> |
|
|
|
<div class="platform-info"> |
|
|
|
<div class="platform-name">{{ platform.name }}</div> |
|
|
|
<div class="platform-type">{{ platform.type }}</div> |
|
|
|
</div> |
|
|
|
<div class="platform-status"> |
|
|
|
<span class="status-dot" :class="platform.status"></span> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</el-tab-pane> |
|
|
|
|
|
|
|
<el-tab-pane label="地面" name="ground"> |
|
|
|
<div class="platform-list"> |
|
|
|
<div |
|
|
|
v-for="platform in groundPlatforms" |
|
|
|
:key="platform.id" |
|
|
|
class="platform-item" |
|
|
|
@click="openPlatformDialog(platform)" |
|
|
|
> |
|
|
|
<div class="platform-icon" :style="{ color: platform.color }"> |
|
|
|
<i :class="platform.icon"></i> |
|
|
|
</div> |
|
|
|
<div class="platform-info"> |
|
|
|
<div class="platform-name">{{ platform.name }}</div> |
|
|
|
<div class="platform-type">{{ platform.type }}</div> |
|
|
|
</div> |
|
|
|
<div class="platform-status"> |
|
|
|
<span class="status-dot" :class="platform.status"></span> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</el-tab-pane> |
|
|
|
</el-tabs> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<right-panel |
|
|
|
:is-hidden="isRightPanelHidden" |
|
|
|
:active-tab="activeRightTab" |
|
|
|
:routes="routes" |
|
|
|
:selected-route-id="selectedRouteId" |
|
|
|
:selected-route-details="selectedRouteDetails" |
|
|
|
:conflicts="conflicts" |
|
|
|
:conflict-count="conflictCount" |
|
|
|
:air-platforms="airPlatforms" |
|
|
|
:sea-platforms="seaPlatforms" |
|
|
|
:ground-platforms="groundPlatforms" |
|
|
|
@hide="hideRightPanel" |
|
|
|
@tab-change="activeRightTab = $event" |
|
|
|
@select-route="selectRoute" |
|
|
|
@open-route-dialog="openRouteDialog" |
|
|
|
@open-waypoint-dialog="openWaypointDialog" |
|
|
|
@add-waypoint="addWaypoint" |
|
|
|
@cancel-route="cancelRoute" |
|
|
|
@view-conflict="viewConflict" |
|
|
|
@resolve-conflict="resolveConflict" |
|
|
|
@run-conflict-check="runConflictCheck" |
|
|
|
@open-platform-dialog="openPlatformDialog" |
|
|
|
/> |
|
|
|
|
|
|
|
<!-- 底部时间轴(最初版本的样式)- 蓝色主题 --> |
|
|
|
<div |
|
|
|
@ -614,6 +376,8 @@ 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: { |
|
|
|
@ -621,7 +385,9 @@ export default { |
|
|
|
OnlineMembersDialog, |
|
|
|
PlatformEditDialog, |
|
|
|
RouteEditDialog, |
|
|
|
WaypointEditDialog |
|
|
|
WaypointEditDialog, |
|
|
|
LeftMenu, |
|
|
|
RightPanel |
|
|
|
}, |
|
|
|
data() { |
|
|
|
return { |
|
|
|
@ -657,8 +423,6 @@ export default { |
|
|
|
// 左侧菜单栏 |
|
|
|
isMenuHidden: true, // 是否完全隐藏左侧菜单 |
|
|
|
activeMenu: 'file', |
|
|
|
hoverMenu: '', |
|
|
|
showMenuTooltip: false, |
|
|
|
|
|
|
|
// 右侧面板控制 |
|
|
|
isRightPanelHidden: true, // 是否完全隐藏右侧面板 |
|
|
|
@ -1042,19 +806,6 @@ export default { |
|
|
|
} |
|
|
|
}, |
|
|
|
|
|
|
|
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; |
|
|
|
@ -1514,609 +1265,6 @@ 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; |
|
|
|
|