Files
arboris-novel/frontend/src/components/novel-detail/RelationshipsSection.vue
2025-10-21 09:51:27 +08:00

86 lines
3.4 KiB
Vue

<template>
<div class="space-y-6">
<div class="flex items-center justify-between">
<div>
<h2 class="text-2xl font-bold text-slate-900">人物关系</h2>
<p class="text-sm text-slate-500">角色之间的纽带与冲突</p>
</div>
<button
v-if="editable"
type="button"
class="text-gray-400 hover:text-indigo-600 transition-colors"
@click="emitEdit('relationships', '人物关系', data?.relationships)">
<svg class="h-6 w-6" viewBox="0 0 20 20" fill="currentColor">
<path d="M17.414 2.586a2 2 0 00-2.828 0L7 10.172V13h2.828l7.586-7.586a2 2 0 000-2.828z" />
<path fill-rule="evenodd" d="M2 6a2 2 0 012-2h4a1 1 0 010 2H4v10h10v-4a1 1 0 112 0v4a2 2 0 01-2 2H4a2 2 0 01-2-2V6z" clip-rule="evenodd" />
</svg>
</button>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div
v-for="(relation, index) in relationships"
:key="index"
class="bg-white/95 rounded-2xl border border-slate-200 shadow-sm p-6">
<div class="flex items-center justify-between">
<div class="flex items-center space-x-3">
<div class="w-10 h-10 rounded-full bg-indigo-100 flex items-center justify-center text-indigo-600 font-semibold">
{{ relation.character_from?.slice(0, 1) || '角' }}
</div>
<span class="font-semibold text-slate-900 truncate">{{ relation.character_from || '未知角色' }}</span>
</div>
<svg class="text-slate-400" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14"/><path d="m12 5 7 7-7 7"/></svg>
<div class="flex items-center space-x-3">
<span class="font-semibold text-slate-900 truncate">{{ relation.character_to || '未知角色' }}</span>
<div class="w-10 h-10 rounded-full bg-emerald-100 flex items-center justify-center text-emerald-600 font-semibold">
{{ relation.character_to?.slice(0, 1) || '角' }}
</div>
</div>
</div>
<div class="mt-4 bg-slate-50 border border-slate-100 rounded-xl p-4 text-center">
<p class="text-sm font-semibold text-slate-700">{{ relation.relationship_type || '关系' }}</p>
<p class="text-xs text-slate-500 leading-5 mt-1">{{ relation.description || '暂无描述' }}</p>
</div>
</div>
<div v-if="!relationships.length" class="bg-white/95 rounded-2xl border border-dashed border-slate-300 p-10 text-center text-slate-400">
暂无人际关系信息
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { computed, defineEmits, defineProps } from 'vue'
interface RelationshipItem {
character_from?: string
character_to?: string
relationship_type?: string
description?: string
}
const props = defineProps<{
data: { relationships?: RelationshipItem[] } | null
editable?: boolean
}>()
const emit = defineEmits<{
(e: 'edit', payload: { field: string; title: string; value: any }): void
}>()
const relationships = computed(() => props.data?.relationships || [])
const emitEdit = (field: string, title: string, value: any) => {
if (!props.editable) return
emit('edit', { field, title, value })
}
</script>
<script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({
name: 'RelationshipsSection'
})
</script>