Files
matrix-show/frontend/src/components/ClueBoard.vue
T
2026-06-04 17:59:53 +08:00

59 lines
2.4 KiB
Vue

<template>
<div class="clue-board">
<div class="board-header">
<h3>📋 线索本</h3>
<span class="clue-count">{{ unlockedCount }}/{{ clues.length }}</span>
</div>
<div class="board-body">
<div v-if="clues.length === 0" class="board-empty">暂无线索</div>
<div
v-for="clue in clues"
:key="clue.id"
class="clue-item"
:class="{ unlocked: clue.is_unlocked }"
>
<div class="clue-header">
<span class="clue-type">{{ TYPE_ICONS[clue.clue_type] || '📌' }}</span>
<span class="clue-name">{{ clue.name }}</span>
<span v-if="!clue.is_unlocked" class="clue-hidden">🔒</span>
<span v-else class="clue-unlocked">🔓</span>
</div>
<div v-if="clue.is_unlocked" class="clue-desc">{{ clue.content }}</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { computed } from 'vue'
import type { Clue } from '../../stores/clueStore'
const props = defineProps<{
clues: Clue[]
}>()
const TYPE_ICONS: Record<string, string> = {
physical: '🔧',
testimony: '💬',
motive: '💰',
alibi: '⏰',
forensic: '🔬',
}
const unlockedCount = computed(() => props.clues.filter((c) => c.is_unlocked).length)
</script>
<style scoped>
.clue-board { display: flex; flex-direction: column; height: 100%; }
.board-header { display: flex; justify-content: space-between; align-items: center; padding: 0.75rem 1rem; border-bottom: 1px solid var(--border-color); }
.board-header h3 { font-size: 0.9rem; font-weight: 600; }
.clue-count { font-size: 0.7rem; color: var(--text-secondary); }
.board-body { flex: 1; overflow-y: auto; padding: 0.5rem; }
.board-empty { display: flex; align-items: center; justify-content: center; height: 80px; color: var(--text-muted); font-size: 0.8rem; }
.clue-item { padding: 0.5rem; margin-bottom: 0.5rem; border-radius: var(--border-radius); background: var(--bg-card); border: 1px solid var(--border-color); transition: all 0.3s ease; }
.clue-item.unlocked { border-color: var(--accent-success); background: rgba(107, 203, 119, 0.05); }
.clue-header { display: flex; align-items: center; gap: 0.5rem; }
.clue-name { flex: 1; font-size: 0.85rem; font-weight: 500; }
.clue-desc { margin-top: 0.4rem; padding-top: 0.4rem; border-top: 1px solid var(--border-color); font-size: 0.8rem; color: var(--text-secondary); line-height: 1.5; }
</style>