Files
ogame-vue-ts/src/components/CardUnlockOverlay.vue
谦君 9b9fda0400 feat: 新增NPC与外交逻辑,优化UI组件结构
重构并精简了部分UI组件,移除冗余弹窗与详情组件,新增NPC相关逻辑(npcBehaviorLogic、npcGrowthLogic、npcStore等)及外交逻辑(diplomaticLogic、DiplomacyView)。完善分页、标签、复选框等通用UI组件。优化战报弹窗,调整README下载链接为相对路径,修复部分国际化内容。
2025-12-15 08:23:45 +08:00

104 lines
4.1 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div v-if="!isUnlocked" class="absolute inset-0 z-10 bg-background/70 backdrop-blur-[2px] rounded-lg flex items-center justify-center">
<div class="text-center p-4 space-y-2">
<div class="flex justify-center">
<div class="rounded-full bg-muted p-2">
<Lock :size="20" class="text-muted-foreground" />
</div>
</div>
<p class="text-xs font-medium text-muted-foreground">{{ t('common.locked') }}</p>
<Button variant="outline" size="sm" @click="showRequirements" class="text-xs">
{{ t('common.viewRequirements') }}
</Button>
</div>
<!-- 前置条件详情对话框 -->
<AlertDialog :open="requirementsDialogOpen" @update:open="requirementsDialogOpen = $event">
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>{{ requirementsDialogTitle }}</AlertDialogTitle>
<AlertDialogDescription class="whitespace-pre-line">
{{ requirementsDialogMessage }}
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogAction>{{ t('common.confirm') }}</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
</div>
</template>
<script setup lang="ts">
import { computed, ref } from 'vue'
import { useGameStore } from '@/stores/gameStore'
import { useI18n } from '@/composables/useI18n'
import { useGameConfig } from '@/composables/useGameConfig'
import { BuildingType, TechnologyType } from '@/types/game'
import { Lock } from 'lucide-vue-next'
import { Button } from '@/components/ui/button'
import {
AlertDialog,
AlertDialogAction,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle
} from '@/components/ui/alert-dialog'
import * as publicLogic from '@/logic/publicLogic'
interface Props {
requirements?: Partial<Record<BuildingType | TechnologyType, number>>
currentLevel?: number // 当前建筑/科技等级,用于判断是否已解锁
}
const props = defineProps<Props>()
const gameStore = useGameStore()
const { t } = useI18n()
const { BUILDINGS, TECHNOLOGIES } = useGameConfig()
// AlertDialog 状态
const requirementsDialogOpen = ref(false)
const requirementsDialogTitle = ref('')
const requirementsDialogMessage = ref('')
const isUnlocked = computed(() => {
// 如果已经建造过level > 0则认为已解锁不显示遮罩
if (props.currentLevel !== undefined && props.currentLevel > 0) return true
if (!props.requirements || !gameStore.currentPlanet) return true
return publicLogic.checkRequirements(gameStore.currentPlanet, gameStore.player.technologies, props.requirements)
})
const getRequirementsList = (): string => {
if (!props.requirements || !gameStore.currentPlanet) return ''
const lines: string[] = []
for (const [key, requiredLevel] of Object.entries(props.requirements)) {
// 检查是否为建筑类型
if (Object.values(BuildingType).includes(key as BuildingType)) {
const buildingType = key as BuildingType
const currentLevel = gameStore.currentPlanet.buildings[buildingType] || 0
const name = BUILDINGS.value[buildingType]?.name || buildingType
const status = currentLevel >= requiredLevel ? '✓' : '✗'
lines.push(`${status} ${name}: Lv ${requiredLevel} (${t('common.current')}: Lv ${currentLevel})`)
}
// 检查是否为科技类型
else if (Object.values(TechnologyType).includes(key as TechnologyType)) {
const techType = key as TechnologyType
const currentLevel = gameStore.player.technologies[techType] || 0
const name = TECHNOLOGIES.value[techType]?.name || techType
const status = currentLevel >= requiredLevel ? '✓' : '✗'
lines.push(`${status} ${name}: Lv ${requiredLevel} (${t('common.current')}: Lv ${currentLevel})`)
}
}
return lines.join('\n')
}
const showRequirements = () => {
requirementsDialogTitle.value = t('common.requirementsNotMet')
requirementsDialogMessage.value = getRequirementsList()
requirementsDialogOpen.value = true
}
</script>