142 lines
3.2 KiB
Vue
142 lines
3.2 KiB
Vue
<!-- WeaponStatsPanel.vue - 武器统计面板组件 -->
|
|
<template>
|
|
<div class="weapon-stats-panel">
|
|
<div class="stats-header">
|
|
<h3>武器统计</h3>
|
|
<el-tag :type="statusType" size="small">{{ statusText }}</el-tag>
|
|
</div>
|
|
|
|
<div class="stats-content">
|
|
<div class="weapon-item" v-for="weapon in weapons" :key="weapon.id">
|
|
<div class="weapon-info">
|
|
<span class="weapon-name">{{ weapon.name }}</span>
|
|
<span class="weapon-count">{{ weapon.count }}</span>
|
|
</div>
|
|
<div class="weapon-bar">
|
|
<div
|
|
class="weapon-progress"
|
|
:style="{ width: `${weapon.readiness}%` }"
|
|
:class="`weapon-progress--${weapon.type}`"
|
|
></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { computed } from 'vue'
|
|
|
|
interface Weapon {
|
|
id: string
|
|
name: string
|
|
count: number
|
|
readiness: number
|
|
type: 'primary' | 'secondary' | 'defense'
|
|
}
|
|
|
|
const props = defineProps<{
|
|
weapons?: Weapon[]
|
|
status?: 'ready' | 'loading' | 'disabled'
|
|
}>()
|
|
|
|
const weapons = computed(() => props.weapons || [
|
|
{ id: '1', name: '主炮', count: 2, readiness: 100, type: 'primary' as const },
|
|
{ id: '2', name: '导弹', count: 8, readiness: 75, type: 'secondary' as const },
|
|
{ id: '3', name: '防空炮', count: 4, readiness: 90, type: 'defense' as const }
|
|
])
|
|
|
|
const statusType = computed(() => {
|
|
switch (props.status) {
|
|
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>
|
|
|
|
<style scoped lang="scss">
|
|
@use 'sass:color';
|
|
@import '@/styles/variables.scss';
|
|
|
|
.weapon-stats-panel {
|
|
padding: $spacing-base;
|
|
background: $bg-secondary;
|
|
border-radius: $border-radius-base;
|
|
border: 1px solid $border-light;
|
|
}
|
|
|
|
.stats-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: $spacing-base;
|
|
|
|
h3 {
|
|
margin: 0;
|
|
color: $text-primary;
|
|
font-size: $font-size-lg;
|
|
font-weight: $font-weight-semibold;
|
|
}
|
|
}
|
|
|
|
.weapon-item {
|
|
margin-bottom: $spacing-sm;
|
|
|
|
&:last-child {
|
|
margin-bottom: 0;
|
|
}
|
|
}
|
|
|
|
.weapon-info {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: $spacing-xs;
|
|
}
|
|
|
|
.weapon-name {
|
|
color: $text-primary;
|
|
font-weight: $font-weight-medium;
|
|
}
|
|
|
|
.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 {
|
|
background: linear-gradient(90deg, $warning-color, color.adjust($warning-color, $lightness: 10%));
|
|
}
|
|
|
|
&--defense {
|
|
background: linear-gradient(90deg, $success-color, color.adjust($success-color, $lightness: 10%));
|
|
}
|
|
}
|
|
</style>
|