处理页面
This commit is contained in:
parent
81b502f993
commit
c22880375d
585
src/components/entity/MissionConfigPanel.vue
Normal file
585
src/components/entity/MissionConfigPanel.vue
Normal file
@ -0,0 +1,585 @@
|
|||||||
|
<!-- MissionConfigPanel.vue - 任务配置面板组件 -->
|
||||||
|
<template>
|
||||||
|
<div class="mission-config-panel">
|
||||||
|
<!-- 标签页导航 -->
|
||||||
|
<div class="tab-navigation">
|
||||||
|
<div
|
||||||
|
v-for="tab in tabs"
|
||||||
|
:key="tab.key"
|
||||||
|
class="tab-item"
|
||||||
|
:class="{ 'active': activeTab === tab.key }"
|
||||||
|
@click="activeTab = tab.key"
|
||||||
|
>
|
||||||
|
{{ tab.label }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 标签页内容 -->
|
||||||
|
<div class="tab-content">
|
||||||
|
<!-- 航线规划 -->
|
||||||
|
<div v-if="activeTab === 'route'" class="tab-panel route-panel">
|
||||||
|
<div class="panel-section">
|
||||||
|
<h4>航线规划</h4>
|
||||||
|
<p>航线规划功能正在开发中...</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 武器装备 -->
|
||||||
|
<div v-if="activeTab === 'weapon'" class="tab-panel weapon-panel">
|
||||||
|
<!-- 基础信息 -->
|
||||||
|
<div class="panel-section basic-info">
|
||||||
|
<h4>基础信息</h4>
|
||||||
|
<div class="info-grid">
|
||||||
|
<div class="info-item">
|
||||||
|
<label>名称</label>
|
||||||
|
<el-select v-model="entityConfig.name" size="small">
|
||||||
|
<el-option label="J-16" value="J-16" />
|
||||||
|
<el-option label="J-20" value="J-20" />
|
||||||
|
<el-option label="J-10" value="J-10" />
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
<div class="info-item">
|
||||||
|
<label>名称</label>
|
||||||
|
<el-input v-model="entityConfig.displayName" size="small" />
|
||||||
|
</div>
|
||||||
|
<div class="info-item">
|
||||||
|
<label>选择传感</label>
|
||||||
|
<el-select v-model="entityConfig.armorType" size="small">
|
||||||
|
<el-option label="红方" value="red" />
|
||||||
|
<el-option label="蓝方" value="blue" />
|
||||||
|
<el-option label="中立" value="neutral" />
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
<div class="info-item">
|
||||||
|
<label>任务类型</label>
|
||||||
|
<el-select v-model="entityConfig.missionType" size="small">
|
||||||
|
<el-option label="扫荡" value="sweep" />
|
||||||
|
<el-option label="侦察" value="scout" />
|
||||||
|
<el-option label="攻击" value="attack" />
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
<div class="info-item">
|
||||||
|
<label>包络最高高度</label>
|
||||||
|
<el-select v-model="entityConfig.maxAltitude" size="small">
|
||||||
|
<el-option label="10000m" value="10000" />
|
||||||
|
<el-option label="15000m" value="15000" />
|
||||||
|
<el-option label="20000m" value="20000" />
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
<div class="info-item">
|
||||||
|
<label>包络最低高度</label>
|
||||||
|
<el-select v-model="entityConfig.minAltitude" size="small">
|
||||||
|
<el-option label="100m" value="100" />
|
||||||
|
<el-option label="500m" value="500" />
|
||||||
|
<el-option label="1000m" value="1000" />
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 武器挂载 -->
|
||||||
|
<div class="panel-section weapon-mount">
|
||||||
|
<h4>武器挂载</h4>
|
||||||
|
<div class="weapon-schemes">
|
||||||
|
<div
|
||||||
|
v-for="scheme in weaponSchemes"
|
||||||
|
:key="scheme.id"
|
||||||
|
class="weapon-scheme"
|
||||||
|
:class="{
|
||||||
|
'active': selectedWeaponScheme === scheme.id,
|
||||||
|
'disabled': !scheme.available
|
||||||
|
}"
|
||||||
|
@click="selectWeaponScheme(scheme.id)"
|
||||||
|
>
|
||||||
|
<div class="scheme-indicator"></div>
|
||||||
|
<span class="scheme-name">{{ scheme.name }}</span>
|
||||||
|
<span v-if="!scheme.available" class="scheme-status">北方暂不可用</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 武器挂载示意图 -->
|
||||||
|
<div class="weapon-diagram">
|
||||||
|
<div class="aircraft-container">
|
||||||
|
<!-- 飞机主体 -->
|
||||||
|
<div class="aircraft-body">
|
||||||
|
<svg viewBox="0 0 400 200" class="aircraft-svg">
|
||||||
|
<!-- 飞机轮廓 -->
|
||||||
|
<path d="M200 20 L220 40 L380 60 L390 80 L380 100 L340 120 L200 140 L60 120 L20 100 L10 80 L20 60 L180 40 Z"
|
||||||
|
fill="#e0e0e0" stroke="#999" stroke-width="2"/>
|
||||||
|
<!-- 机翼 -->
|
||||||
|
<path d="M80 80 L150 70 L200 80 L250 70 L320 80 L250 90 L200 100 L150 90 Z"
|
||||||
|
fill="#f0f0f0" stroke="#999" stroke-width="1"/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 武器挂载点 -->
|
||||||
|
<div class="weapon-mount-points">
|
||||||
|
<div class="mount-point mount-1" v-if="mountedWeapons[0]">
|
||||||
|
<img :src="getWeaponIcon(mountedWeapons[0])" :alt="mountedWeapons[0].name" />
|
||||||
|
<span class="mount-number">1</span>
|
||||||
|
</div>
|
||||||
|
<div class="mount-point mount-2" v-if="mountedWeapons[1]">
|
||||||
|
<img :src="getWeaponIcon(mountedWeapons[1])" :alt="mountedWeapons[1].name" />
|
||||||
|
<span class="mount-number">2</span>
|
||||||
|
</div>
|
||||||
|
<div class="mount-point mount-3" v-if="mountedWeapons[2]">
|
||||||
|
<img :src="getWeaponIcon(mountedWeapons[2])" :alt="mountedWeapons[2].name" />
|
||||||
|
<span class="mount-number">3</span>
|
||||||
|
</div>
|
||||||
|
<div class="mount-point mount-4" v-if="mountedWeapons[3]">
|
||||||
|
<img :src="getWeaponIcon(mountedWeapons[3])" :alt="mountedWeapons[3].name" />
|
||||||
|
<span class="mount-number">4</span>
|
||||||
|
</div>
|
||||||
|
<div class="mount-point mount-5" v-if="mountedWeapons[4]">
|
||||||
|
<img :src="getWeaponIcon(mountedWeapons[4])" :alt="mountedWeapons[4].name" />
|
||||||
|
<span class="mount-number">5</span>
|
||||||
|
</div>
|
||||||
|
<div class="mount-point mount-6" v-if="mountedWeapons[5]">
|
||||||
|
<img :src="getWeaponIcon(mountedWeapons[5])" :alt="mountedWeapons[5].name" />
|
||||||
|
<span class="mount-number">6</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 武器信息描述 -->
|
||||||
|
<div class="weapon-description">
|
||||||
|
<p>武器挂载方案一 *方案创建于2019.7.11</p>
|
||||||
|
<p>这是一段关于武器挂载信息的详细描述文本</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 燃油管理 -->
|
||||||
|
<div class="fuel-management">
|
||||||
|
<div class="fuel-info">
|
||||||
|
<span class="fuel-label">油量</span>
|
||||||
|
<span class="fuel-amount">1200 kg</span>
|
||||||
|
</div>
|
||||||
|
<div class="fuel-bar">
|
||||||
|
<div class="fuel-progress" :style="{ width: `${fuelPercentage}%` }"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 雷达传感器 -->
|
||||||
|
<div v-if="activeTab === 'radar'" class="tab-panel radar-panel">
|
||||||
|
<div class="panel-section">
|
||||||
|
<h4>雷达传感器</h4>
|
||||||
|
<p>雷达传感器配置功能正在开发中...</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 光电传感器 -->
|
||||||
|
<div v-if="activeTab === 'optical'" class="tab-panel optical-panel">
|
||||||
|
<div class="panel-section">
|
||||||
|
<h4>光电传感器</h4>
|
||||||
|
<p>光电传感器配置功能正在开发中...</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 通信规划 -->
|
||||||
|
<div v-if="activeTab === 'communication'" class="tab-panel communication-panel">
|
||||||
|
<div class="panel-section">
|
||||||
|
<h4>通信规划</h4>
|
||||||
|
<p>通信规划功能正在开发中...</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, computed } from 'vue'
|
||||||
|
|
||||||
|
interface EntityConfig {
|
||||||
|
name: string
|
||||||
|
displayName: string
|
||||||
|
armorType: string
|
||||||
|
missionType: string
|
||||||
|
maxAltitude: string
|
||||||
|
minAltitude: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface WeaponScheme {
|
||||||
|
id: string
|
||||||
|
name: string
|
||||||
|
available: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
interface WeaponItem {
|
||||||
|
id: string
|
||||||
|
name: string
|
||||||
|
type: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
entityConfig: EntityConfig
|
||||||
|
weaponSchemes: WeaponScheme[]
|
||||||
|
selectedWeaponScheme: string
|
||||||
|
fuelPercentage: number
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
'update:entityConfig': [config: EntityConfig]
|
||||||
|
'update:selectedWeaponScheme': [schemeId: string]
|
||||||
|
'weapon-scheme-select': [schemeId: string]
|
||||||
|
}>()
|
||||||
|
|
||||||
|
// 标签页配置
|
||||||
|
const tabs = [
|
||||||
|
{ key: 'route', label: '航线规划' },
|
||||||
|
{ key: 'weapon', label: '武器装备' },
|
||||||
|
{ key: 'radar', label: '雷达传感器' },
|
||||||
|
{ key: 'optical', label: '光电传感器' },
|
||||||
|
{ key: 'communication', label: '通信规划' }
|
||||||
|
]
|
||||||
|
|
||||||
|
const activeTab = ref('weapon')
|
||||||
|
|
||||||
|
// 实体配置的响应式副本
|
||||||
|
const entityConfig = computed({
|
||||||
|
get: () => props.entityConfig,
|
||||||
|
set: (value) => emit('update:entityConfig', value)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 选中的武器方案
|
||||||
|
const selectedWeaponScheme = computed({
|
||||||
|
get: () => props.selectedWeaponScheme,
|
||||||
|
set: (value) => emit('update:selectedWeaponScheme', value)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 模拟挂载的武器
|
||||||
|
const mountedWeapons = ref([
|
||||||
|
{ id: '1', name: 'PL-8', type: 'missile' },
|
||||||
|
{ id: '2', name: 'AIM-7', type: 'missile' },
|
||||||
|
{ id: '3', name: 'AIM-120', type: 'missile' },
|
||||||
|
{ id: '4', name: 'PL-12', type: 'missile' },
|
||||||
|
{ id: '5', name: 'PL-15', type: 'missile' },
|
||||||
|
{ id: '6', name: 'PL-10', type: 'missile' }
|
||||||
|
])
|
||||||
|
|
||||||
|
// 方法
|
||||||
|
const selectWeaponScheme = (schemeId: string) => {
|
||||||
|
const scheme = props.weaponSchemes.find(s => s.id === schemeId)
|
||||||
|
if (scheme?.available) {
|
||||||
|
emit('weapon-scheme-select', schemeId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const getWeaponIcon = (weapon: WeaponItem) => {
|
||||||
|
// 返回武器图标的占位符
|
||||||
|
return '/weapon-icons/missile.svg'
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@use '@/styles/variables.scss' as *;
|
||||||
|
|
||||||
|
.mission-config-panel {
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
background: rgba(15, 20, 25, 0.6);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 标签页导航
|
||||||
|
.tab-navigation {
|
||||||
|
display: flex;
|
||||||
|
background: rgba(20, 25, 30, 0.8);
|
||||||
|
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-item {
|
||||||
|
padding: 12px 24px;
|
||||||
|
color: rgba(255, 255, 255, 0.7);
|
||||||
|
cursor: pointer;
|
||||||
|
border-bottom: 2px solid transparent;
|
||||||
|
transition: all 0.3s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: rgba(255, 255, 255, 0.9);
|
||||||
|
background: rgba(255, 255, 255, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
color: #409eff;
|
||||||
|
border-bottom-color: #409eff;
|
||||||
|
background: rgba(64, 158, 255, 0.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 标签页内容
|
||||||
|
.tab-content {
|
||||||
|
flex: 1;
|
||||||
|
overflow-y: auto;
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-panel {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-section {
|
||||||
|
margin-bottom: 24px;
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
color: #ffffff;
|
||||||
|
margin: 0 0 16px 0;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 基础信息
|
||||||
|
.basic-info {
|
||||||
|
.info-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(3, 1fr);
|
||||||
|
gap: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-item {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 6px;
|
||||||
|
|
||||||
|
label {
|
||||||
|
color: rgba(255, 255, 255, 0.8);
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-select),
|
||||||
|
:deep(.el-input) {
|
||||||
|
.el-input__wrapper {
|
||||||
|
background: rgba(255, 255, 255, 0.1);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-input__inner {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-select-dropdown) {
|
||||||
|
background: rgba(30, 35, 40, 0.95);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||||
|
|
||||||
|
.el-select-dropdown__item {
|
||||||
|
color: #ffffff;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: rgba(64, 158, 255, 0.2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 武器挂载
|
||||||
|
.weapon-mount {
|
||||||
|
.weapon-schemes {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8px;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.weapon-scheme {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
padding: 8px 12px;
|
||||||
|
background: rgba(255, 255, 255, 0.05);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||||
|
border-radius: 6px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s;
|
||||||
|
|
||||||
|
&:hover:not(.disabled) {
|
||||||
|
background: rgba(255, 255, 255, 0.1);
|
||||||
|
border-color: rgba(255, 255, 255, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
background: rgba(64, 158, 255, 0.2);
|
||||||
|
border-color: #409eff;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.disabled {
|
||||||
|
opacity: 0.5;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scheme-indicator {
|
||||||
|
width: 12px;
|
||||||
|
height: 12px;
|
||||||
|
border: 2px solid rgba(255, 255, 255, 0.4);
|
||||||
|
border-radius: 50%;
|
||||||
|
|
||||||
|
.active & {
|
||||||
|
background: #409eff;
|
||||||
|
border-color: #409eff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.scheme-name {
|
||||||
|
flex: 1;
|
||||||
|
color: #ffffff;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scheme-status {
|
||||||
|
color: #f56c6c;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 武器示意图
|
||||||
|
.weapon-diagram {
|
||||||
|
background: rgba(0, 0, 0, 0.3);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 24px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
|
||||||
|
.aircraft-container {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
min-height: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.aircraft-body {
|
||||||
|
.aircraft-svg {
|
||||||
|
width: 400px;
|
||||||
|
height: 200px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.weapon-mount-points {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
.mount-point {
|
||||||
|
position: absolute;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 40px;
|
||||||
|
height: 20px;
|
||||||
|
filter: brightness(0.8);
|
||||||
|
}
|
||||||
|
|
||||||
|
.mount-number {
|
||||||
|
background: #409eff;
|
||||||
|
color: #ffffff;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.mount-1 { top: 50px; left: 50px; }
|
||||||
|
&.mount-2 { top: 80px; left: 120px; }
|
||||||
|
&.mount-3 { top: 30px; left: 200px; }
|
||||||
|
&.mount-4 { top: 30px; right: 200px; }
|
||||||
|
&.mount-5 { top: 80px; right: 120px; }
|
||||||
|
&.mount-6 { top: 50px; right: 50px; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.weapon-description {
|
||||||
|
margin-top: 16px;
|
||||||
|
padding-top: 16px;
|
||||||
|
border-top: 1px solid rgba(255, 255, 255, 0.1);
|
||||||
|
|
||||||
|
p {
|
||||||
|
color: rgba(255, 255, 255, 0.7);
|
||||||
|
margin: 0 0 8px 0;
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 1.4;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 燃油管理
|
||||||
|
.fuel-management {
|
||||||
|
background: rgba(0, 0, 0, 0.2);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 16px;
|
||||||
|
|
||||||
|
.fuel-info {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
|
||||||
|
.fuel-label {
|
||||||
|
color: rgba(255, 255, 255, 0.8);
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fuel-amount {
|
||||||
|
color: #ffffff;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.fuel-bar {
|
||||||
|
height: 8px;
|
||||||
|
background: rgba(255, 255, 255, 0.1);
|
||||||
|
border-radius: 4px;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.fuel-progress {
|
||||||
|
height: 100%;
|
||||||
|
background: linear-gradient(90deg, #409eff, #66b1ff);
|
||||||
|
transition: width 0.3s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 响应式设计
|
||||||
|
@media (max-width: $breakpoint-md) {
|
||||||
|
.tab-navigation {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-item {
|
||||||
|
padding: 8px 16px;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.basic-info .info-grid {
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: $breakpoint-sm) {
|
||||||
|
.basic-info .info-grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.weapon-diagram .aircraft-svg {
|
||||||
|
width: 300px;
|
||||||
|
height: 150px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -1,23 +1,31 @@
|
|||||||
<!-- WeaponStatsPanel.vue - 武器统计面板组件 -->
|
<!-- WeaponStatsPanel.vue - 武器统计面板组件 -->
|
||||||
<template>
|
<template>
|
||||||
<div class="weapon-stats-panel">
|
<div class="weapon-stats-panel">
|
||||||
<div class="stats-header">
|
<!-- 当前挂载重量 -->
|
||||||
<h3>武器统计</h3>
|
<div class="weight-section">
|
||||||
<el-tag :type="statusType" size="small">{{ statusText }}</el-tag>
|
<div class="weight-header">
|
||||||
|
<h3>当前挂载重量</h3>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="stats-content">
|
<div class="weight-display">
|
||||||
<div class="weapon-item" v-for="weapon in weapons" :key="weapon.id">
|
<div class="weight-value">
|
||||||
<div class="weapon-info">
|
<span class="weight-number">{{ totalWeight }}t</span>
|
||||||
<span class="weapon-name">{{ weapon.name }}</span>
|
<span class="weight-change" :class="{ 'positive': weightChange > 0, 'negative': weightChange < 0 }">
|
||||||
<span class="weapon-count">{{ weapon.count }}</span>
|
{{ weightChange > 0 ? '+' : '' }}{{ weightChange }}%
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 武器清单 -->
|
||||||
|
<div class="weapon-inventory">
|
||||||
|
<div class="weapon-list">
|
||||||
|
<div class="weapon-item" v-for="weapon in weaponInventory" :key="weapon.id">
|
||||||
|
<div class="weapon-icon">{{ weapon.icon }}</div>
|
||||||
|
<div class="weapon-details">
|
||||||
|
<div class="weapon-name">{{ weapon.name }}</div>
|
||||||
|
<div class="weapon-weight">{{ weapon.weight }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="weapon-bar">
|
|
||||||
<div
|
|
||||||
class="weapon-progress"
|
|
||||||
:style="{ width: `${weapon.readiness}%` }"
|
|
||||||
:class="`weapon-progress--${weapon.type}`"
|
|
||||||
></div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -25,44 +33,31 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed } from 'vue'
|
interface WeaponItem {
|
||||||
|
|
||||||
interface Weapon {
|
|
||||||
id: string
|
id: string
|
||||||
name: string
|
name: string
|
||||||
count: number
|
weight: string
|
||||||
readiness: number
|
icon: string
|
||||||
type: 'primary' | 'secondary' | 'defense'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
weapons?: Weapon[]
|
weaponInventory?: WeaponItem[]
|
||||||
status?: 'ready' | 'loading' | 'disabled'
|
totalWeight?: number
|
||||||
|
weightChange?: number
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const weapons = computed(() => props.weapons || [
|
// 默认武器清单,匹配截图中的内容
|
||||||
{ id: '1', name: '主炮', count: 2, readiness: 100, type: 'primary' as const },
|
const weaponInventory = props.weaponInventory || [
|
||||||
{ id: '2', name: '导弹', count: 8, readiness: 75, type: 'secondary' as const },
|
{ id: '1', name: 'PL-8', weight: '1.6 t', icon: '🚀' },
|
||||||
{ id: '3', name: '防空炮', count: 4, readiness: 90, type: 'defense' as const }
|
{ id: '2', name: 'Aim-7雷管', weight: '1.6 t', icon: '🚀' },
|
||||||
])
|
{ id: '3', name: 'AIM-120闪电拉姆', weight: '1.6 t', icon: '🚀' },
|
||||||
|
{ id: '4', name: 'PL-12', weight: '1.6 t', icon: '🚀' },
|
||||||
|
{ id: '5', name: 'PL-15', weight: '1.6 t', icon: '🚀' },
|
||||||
|
{ id: '6', name: 'PL-10', weight: '1.6 t', icon: '🚀' }
|
||||||
|
]
|
||||||
|
|
||||||
const statusType = computed(() => {
|
const totalWeight = props.totalWeight || 16
|
||||||
switch (props.status) {
|
const weightChange = props.weightChange || 19.6
|
||||||
case 'ready': return 'success'
|
|
||||||
case 'loading': return 'warning'
|
|
||||||
case 'disabled': return 'danger'
|
|
||||||
default: return 'info'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const statusText = computed(() => {
|
|
||||||
switch (props.status) {
|
|
||||||
case 'ready': return '就绪'
|
|
||||||
case 'loading': return '装填中'
|
|
||||||
case 'disabled': return '停用'
|
|
||||||
default: return '未知'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@ -70,72 +65,114 @@ const statusText = computed(() => {
|
|||||||
@use '@/styles/variables.scss' as *;
|
@use '@/styles/variables.scss' as *;
|
||||||
|
|
||||||
.weapon-stats-panel {
|
.weapon-stats-panel {
|
||||||
padding: $spacing-base;
|
height: 100%;
|
||||||
background: $bg-secondary;
|
padding: 16px;
|
||||||
border-radius: $border-radius-base;
|
background: rgba(15, 20, 25, 0.8);
|
||||||
border: 1px solid $border-light;
|
color: #ffffff;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stats-header {
|
// 重量显示区域
|
||||||
display: flex;
|
.weight-section {
|
||||||
justify-content: space-between;
|
margin-bottom: 24px;
|
||||||
align-items: center;
|
|
||||||
margin-bottom: $spacing-base;
|
.weight-header {
|
||||||
|
margin-bottom: 12px;
|
||||||
|
|
||||||
h3 {
|
h3 {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
color: $text-primary;
|
color: #ffffff;
|
||||||
font-size: $font-size-lg;
|
font-size: 14px;
|
||||||
font-weight: $font-weight-semibold;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.weapon-item {
|
|
||||||
margin-bottom: $spacing-sm;
|
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.weapon-info {
|
.weight-display {
|
||||||
|
.weight-value {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-bottom: $spacing-xs;
|
gap: 8px;
|
||||||
}
|
|
||||||
|
|
||||||
.weapon-name {
|
.weight-number {
|
||||||
color: $text-primary;
|
font-size: 24px;
|
||||||
font-weight: $font-weight-medium;
|
font-weight: 600;
|
||||||
}
|
color: #ffffff;
|
||||||
|
|
||||||
.weapon-count {
|
|
||||||
color: $text-secondary;
|
|
||||||
font-size: $font-size-sm;
|
|
||||||
}
|
|
||||||
|
|
||||||
.weapon-bar {
|
|
||||||
height: 6px;
|
|
||||||
background: $border-light;
|
|
||||||
border-radius: $border-radius-small;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.weapon-progress {
|
|
||||||
height: 100%;
|
|
||||||
transition: width $transition-base;
|
|
||||||
|
|
||||||
&--primary {
|
|
||||||
background: linear-gradient(90deg, $danger-color, color.adjust($danger-color, $lightness: 10%));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&--secondary {
|
.weight-change {
|
||||||
background: linear-gradient(90deg, $warning-color, color.adjust($warning-color, $lightness: 10%));
|
font-size: 12px;
|
||||||
|
font-weight: 500;
|
||||||
|
|
||||||
|
&.positive {
|
||||||
|
color: #67c23a;
|
||||||
}
|
}
|
||||||
|
|
||||||
&--defense {
|
&.negative {
|
||||||
background: linear-gradient(90deg, $success-color, color.adjust($success-color, $lightness: 10%));
|
color: #f56c6c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 武器清单
|
||||||
|
.weapon-inventory {
|
||||||
|
flex: 1;
|
||||||
|
|
||||||
|
.weapon-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.weapon-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 8px;
|
||||||
|
background: rgba(255, 255, 255, 0.05);
|
||||||
|
border-radius: 4px;
|
||||||
|
transition: background 0.3s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: rgba(255, 255, 255, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.weapon-icon {
|
||||||
|
font-size: 16px;
|
||||||
|
width: 20px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.weapon-details {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 2px;
|
||||||
|
|
||||||
|
.weapon-name {
|
||||||
|
color: #ffffff;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.weapon-weight {
|
||||||
|
color: rgba(255, 255, 255, 0.7);
|
||||||
|
font-size: 11px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 响应式设计
|
||||||
|
@media (max-width: $breakpoint-md) {
|
||||||
|
.weapon-stats-panel {
|
||||||
|
padding: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.weight-section .weight-display .weight-value .weight-number {
|
||||||
|
font-size: 20px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -1,10 +1,11 @@
|
|||||||
// 实体管理组件导出
|
// 实体管理组件导出
|
||||||
// ==========================================
|
// ==========================================
|
||||||
|
|
||||||
|
export { default as EntityConfigPanel } from './EntityConfigPanel.vue'
|
||||||
|
export { default as WeaponStatsPanel } from './WeaponStatsPanel.vue'
|
||||||
|
export { default as MissionConfigPanel } from './MissionConfigPanel.vue'
|
||||||
|
|
||||||
// 暂时导出空对象,待后续添加实体相关组件
|
// 暂时导出空对象,待后续添加实体相关组件
|
||||||
// export { default as EntityCard } from './EntityCard.vue'
|
// export { default as EntityCard } from './EntityCard.vue'
|
||||||
// export { default as EntityList } from './EntityList.vue'
|
// export { default as EntityList } from './EntityList.vue'
|
||||||
// export { default as EntityForm } from './EntityForm.vue'
|
// export { default as EntityForm } from './EntityForm.vue'
|
||||||
|
|
||||||
// 临时空导出,避免编译错误
|
|
||||||
export {}
|
|
||||||
@ -97,8 +97,7 @@
|
|||||||
|
|
||||||
<!-- 中央配置区域 -->
|
<!-- 中央配置区域 -->
|
||||||
<div class="center-panel">
|
<div class="center-panel">
|
||||||
<EntityConfigPanel
|
<MissionConfigPanel
|
||||||
v-model:activeTab="activeTab"
|
|
||||||
v-model:entityConfig="entityConfig"
|
v-model:entityConfig="entityConfig"
|
||||||
v-model:selectedWeaponScheme="selectedWeaponScheme"
|
v-model:selectedWeaponScheme="selectedWeaponScheme"
|
||||||
:weapon-schemes="weaponSchemes"
|
:weapon-schemes="weaponSchemes"
|
||||||
@ -124,12 +123,11 @@ import { ref, onMounted } from 'vue'
|
|||||||
import {
|
import {
|
||||||
ArrowLeft, ArrowRight, Search, Refresh, Setting, Folder, Operation, Position
|
ArrowLeft, ArrowRight, Search, Refresh, Setting, Folder, Operation, Position
|
||||||
} from '@element-plus/icons-vue'
|
} from '@element-plus/icons-vue'
|
||||||
import EntityConfigPanel from '@/components/entity/EntityConfigPanel.vue'
|
import MissionConfigPanel from '@/components/entity/MissionConfigPanel.vue'
|
||||||
import WeaponStatsPanel from '@/components/entity/WeaponStatsPanel.vue'
|
import WeaponStatsPanel from '@/components/entity/WeaponStatsPanel.vue'
|
||||||
|
|
||||||
// 响应式数据
|
// 响应式数据
|
||||||
const searchKeyword = ref('')
|
const searchKeyword = ref('')
|
||||||
const activeTab = ref('weapon')
|
|
||||||
const selectedNode = ref<any>(null)
|
const selectedNode = ref<any>(null)
|
||||||
const selectedWeaponScheme = ref('scheme1')
|
const selectedWeaponScheme = ref('scheme1')
|
||||||
const fuelPercentage = ref(75)
|
const fuelPercentage = ref(75)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user