150 lines
3.6 KiB
Vue
150 lines
3.6 KiB
Vue
<template>
|
|
<div class="page-container">
|
|
<div v-if="!pending">
|
|
<div v-if="solution">
|
|
<div class="page-header">
|
|
<el-breadcrumb class="breadcrumb" separator="/">
|
|
<el-breadcrumb-item class="text-md opacity-50">
|
|
<NuxtLink :to="$localePath('/')">{{
|
|
$t('navigation.home')
|
|
}}</NuxtLink>
|
|
</el-breadcrumb-item>
|
|
<el-breadcrumb-item class="text-md opacity-50">
|
|
<NuxtLink :to="$localePath('/solutions')">{{
|
|
$t('navigation.solutions')
|
|
}}</NuxtLink>
|
|
</el-breadcrumb-item>
|
|
<el-breadcrumb-item class="text-md opacity-50">{{
|
|
solution.title
|
|
}}</el-breadcrumb-item>
|
|
</el-breadcrumb>
|
|
</div>
|
|
<div class="page-content">
|
|
<div class="solution-info">
|
|
<h1>{{ solution.title }}</h1>
|
|
<div class="solution-meta">
|
|
<span class="solution-date">
|
|
CreatedAt:
|
|
{{ new Date(solution.createdAt).toLocaleDateString() }}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
<p class="summary">{{ solution.summary }}</p>
|
|
<div class="solution-content">
|
|
<markdown-renderer :content="solution.content || ''" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div v-else class="not-found">
|
|
<el-result
|
|
icon="warning"
|
|
:title="$t('solution-not-found')"
|
|
:sub-title="$t('solution-not-found-desc')"
|
|
>
|
|
<template #extra>
|
|
<el-button type="primary" @click="$router.push('/productions')">
|
|
{{ $t('back-to-solutions') }}
|
|
</el-button>
|
|
</template>
|
|
</el-result>
|
|
</div>
|
|
</div>
|
|
<div v-else class="loading">
|
|
<el-skeleton :rows="5" animated />
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
const route = useRoute();
|
|
const { findOne } = useStrapi();
|
|
const { getStrapiLocale } = useLocalizations();
|
|
const strapiLocale = getStrapiLocale();
|
|
|
|
// 获取路由参数(documentId)
|
|
const documentId = computed(() => route.params.slug as string);
|
|
|
|
const { data, pending, error } = useAsyncData(
|
|
() => `solution-${documentId.value}`,
|
|
() =>
|
|
findOne<Solution>('solutions', documentId.value, {
|
|
populate: '*',
|
|
locale: strapiLocale,
|
|
})
|
|
);
|
|
|
|
const solution = computed(() => data.value?.data ?? null);
|
|
|
|
watch(error, (value) => {
|
|
if (value) {
|
|
console.error('数据获取失败: ', value);
|
|
}
|
|
});
|
|
</script>
|
|
|
|
<style scoped>
|
|
.page-container {
|
|
padding: 1rem;
|
|
min-height: 80vh;
|
|
max-width: 1200px;
|
|
margin: 0 auto;
|
|
}
|
|
|
|
.breadcrumb {
|
|
padding: 1rem;
|
|
margin-bottom: 1rem;
|
|
}
|
|
|
|
.solution-header {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 20px;
|
|
}
|
|
|
|
.solution-header el-image {
|
|
width: 200px;
|
|
height: 200px;
|
|
border-radius: 4px;
|
|
}
|
|
|
|
.page-content h1 {
|
|
font-size: 2rem;
|
|
font-weight: bold;
|
|
color: var(--el-color-primary);
|
|
text-align: center;
|
|
}
|
|
|
|
.solution-meta {
|
|
display: flex;
|
|
justify-content: center;
|
|
gap: 1rem;
|
|
margin-bottom: 0.5rem;
|
|
font-size: 0.8rem;
|
|
color: var(--el-text-color-secondary);
|
|
}
|
|
|
|
.summary {
|
|
font-size: 0.8rem;
|
|
color: var(--el-text-color-secondary);
|
|
text-align: center;
|
|
}
|
|
|
|
.solution-content {
|
|
margin-top: 1rem;
|
|
}
|
|
|
|
.loading {
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
margin-top: 1rem;
|
|
}
|
|
|
|
.not-found {
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
min-height: 400px;
|
|
}
|
|
</style>
|