Files
jinshen-website/app/pages/productions/[...slug].vue
2025-08-15 16:00:55 +08:00

195 lines
4.3 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 class="production-detail">
<div v-if="production">
<!-- 面包屑导航 -->
<el-breadcrumb class="breadcrumb" separator="/">
<el-breadcrumb-item class="text-sm opacity-50" :to="{ path: '/' }">{{ $t('navigation.home')
}}</el-breadcrumb-item>
<el-breadcrumb-item class="text-sm opacity-50" :to="{ path: '/productions' }">{{ $t('productions')
}}</el-breadcrumb-item>
<el-breadcrumb-item class="text-sm opactiy-50">{{ production.title }}</el-breadcrumb-item>
</el-breadcrumb>
<!-- 产品详情内容 -->
<div class="production-header">
<div class="production-image">
<el-image :src="production.image_url" :alt="production.title" fit="contain" />
</div>
<div class="production-info">
<h1>{{ production.title }}</h1>
<p class="summary">{{ production.summary }}</p>
</div>
</div>
<!-- 产品详细描述 -->
<div class="production-content">
<el-tabs v-model="activeName">
<el-tab-pane label="产品详情" name="details">
<h2>{{ production.title }}</h2>
<p class="summary">{{ production.summary }}</p>
</el-tab-pane>
<el-tab-pane label="技术规格" name="specs" />
<el-tab-pane label="相关文档" name="documents" />
</el-tabs>
</div>
</div>
<!-- 加载状态 -->
<div v-else-if="pending" class="loading">
<el-loading-text>{{ $t('loading') }}</el-loading-text>
</div>
<!-- 未找到产品 -->
<div v-else class="not-found">
<el-result icon="warning" :title="$t('product-not-found')" :sub-title="$t('product-not-found-desc')">
<template #extra>
<el-button type="primary" @click="$router.push('/productions')">
{{ $t('back-to-productions') }}
</el-button>
</template>
</el-result>
</div>
</div>
</template>
<script setup lang="ts">
interface ProductionDetail {
id: number
title: string
summary: string
content?: string
image_url: string
slug?: string
}
const route = useRoute()
const router = useRouter()
const { find } = useStrapi()
const production = ref<ProductionDetail | null>(null)
const pending = ref(true)
const activeName = ref('details') // 默认选中概览标签
// 获取路由参数slug 或 id
const productionParam = computed(() => route.params.slug as string)
onMounted(async () => {
try {
const response = await find(`productions/${productionParam.value}`, {
populate: '*',
}) as any
if (response.data) {
const item = response.data
production.value = {
id: item.id,
title: item.title,
summary: item.summary,
content: item.content,
image_url: item.production_image?.url
? `http://192.168.86.5:1337${item.production_image.url}`
: '',
slug: item.slug
}
}
} catch (error) {
console.error('Failed to fetch production:', error)
} finally {
pending.value = false
}
})
const goBack = () => {
router.back()
}
// SEO
useHead({
title: computed(() => production.value?.title || 'Product Detail'),
meta: [
{
name: 'description',
content: computed(() => production.value?.summary || '')
}
]
})
</script>
<style scoped>
.production-detail {
min-height: 60vh;
}
.breadcrumb {
padding: 1rem 1rem;
margin-bottom: 2rem;
}
.breadcrumb-item {
color: var(--el-text-color-regular);
}
.production-header {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 3rem;
margin-bottom: 3rem;
}
.production-image .el-image {
width: 100%;
height: 400px;
border-radius: 8px;
}
.production-info h1 {
margin-top: 2rem;
margin-bottom: 1rem;
font-size: 2rem;
}
.summary {
color: var(--el-color-info);
font-size: 1rem;
line-height: 1.6;
margin-bottom: 2rem;
}
.production-content {
margin-top: 2rem;
}
.production-content h2 {
color: var(--el-text-color-primary);
margin: 0;
}
.loading {
display: flex;
justify-content: center;
align-items: center;
height: 300px;
}
.not-found {
display: flex;
justify-content: center;
align-items: center;
min-height: 400px;
}
/* 响应式设计 */
@media (max-width: 768px) {
.production-header {
grid-template-columns: 1fr;
gap: 2rem;
}
.production-info h1 {
font-size: 2rem;
}
}
</style>